Esempio n. 1
0
        private void LoadSerVolsProject(string Filename)
        {
            Project = new ProjectData(AnalysisMode.Operations);
            Art     = new ArterialData();

            SerVolTables     = FileInputOutput2.DeserializeSerVolTables(Filename);
            Project.FileName = Filename;
        }
        public static ArterialData DeserializeArterialData(string filename)
        {
            FileStream myFileStream = new FileStream(filename, FileMode.Open);
            // Create the XmlSerializer instance.
            XmlSerializer mySerializer = new XmlSerializer(typeof(ArterialData));
            ArterialData  arterial     = (ArterialData)mySerializer.Deserialize(myFileStream);

            myFileStream.Close();

            return(arterial);
        }
        public static void SerializeArterialData(string filename, ArterialData arterial)
        {
            // Writing the file requires a TextWriter.
            //TextWriter myStreamWriter = new StreamWriter(filename);
            FileStream myStream = new FileStream(filename, FileMode.Create);

            // Create the XmlSerializer instance.
            XmlSerializer mySerializer = new XmlSerializer(typeof(ArterialData));

            mySerializer.Serialize(myStream, arterial);
            myStream.Close();
        }
        public static void ChangeArterialVolume(ref ArterialData Arterial, float analysisDirectionDemandVol = 800)
        {
            float minorStreetVolumeRatio = 0.75f;
            float leftTurningPctInt      = 0.12f;
            float rightTurningPctInt     = 0.12f;

            float[] demandVolumesLeft  = { analysisDirectionDemandVol *leftTurningPctInt, analysisDirectionDemandVol *leftTurningPctInt, minorStreetVolumeRatio *analysisDirectionDemandVol *leftTurningPctInt, minorStreetVolumeRatio *analysisDirectionDemandVol *leftTurningPctInt };
            float[] demandVolumesThru  = { analysisDirectionDemandVol *(1 - (leftTurningPctInt + rightTurningPctInt)), analysisDirectionDemandVol *(1 - (leftTurningPctInt + rightTurningPctInt)), minorStreetVolumeRatio *analysisDirectionDemandVol *(1 - (leftTurningPctInt + rightTurningPctInt)), minorStreetVolumeRatio *analysisDirectionDemandVol *(1 - (leftTurningPctInt + rightTurningPctInt)) };
            float[] demandVolumesRight = { analysisDirectionDemandVol *rightTurningPctInt, analysisDirectionDemandVol *rightTurningPctInt, minorStreetVolumeRatio *analysisDirectionDemandVol *rightTurningPctInt, minorStreetVolumeRatio *analysisDirectionDemandVol *rightTurningPctInt };

            foreach (SegmentData Segment in Arterial.Segments)
            {
                foreach (ApproachData Approach in Segment.Intersection.Approaches)
                {
                    int   travelDirectionIndex = (int)Approach.Dir;
                    float totalDemand          = demandVolumesLeft[travelDirectionIndex] + demandVolumesThru[travelDirectionIndex] + demandVolumesRight[travelDirectionIndex];
                    Approach.DemandVolume  = totalDemand;
                    Approach.PctLeftTurns  = (demandVolumesLeft[travelDirectionIndex] / totalDemand) * 100;
                    Approach.PctRightTurns = (demandVolumesRight[travelDirectionIndex] / totalDemand) * 100;

                    foreach (LaneGroupData LaneGroup in Approach.LaneGroups)
                    {
                        if (LaneGroup.Type == LaneMovementsAllowed.LeftOnly)
                        {
                            LaneGroup.DischargeVolume              = demandVolumesLeft[travelDirectionIndex];
                            LaneGroup.DemandVolumeVehPerHr         = demandVolumesLeft[travelDirectionIndex];
                            LaneGroup.DemandVolumeVehPerHrSplit[0] = LaneGroup.DemandVolumeVehPerHr;
                        }
                        if (LaneGroup.Type == LaneMovementsAllowed.ThruRightShared)
                        {
                            LaneGroup.DischargeVolume              = demandVolumesThru[travelDirectionIndex] + demandVolumesRight[travelDirectionIndex];
                            LaneGroup.DemandVolumeVehPerHr         = demandVolumesThru[travelDirectionIndex] + demandVolumesRight[travelDirectionIndex];
                            LaneGroup.PctRightTurns                = demandVolumesRight[travelDirectionIndex] / (demandVolumesThru[travelDirectionIndex] + demandVolumesRight[travelDirectionIndex]) * 100;
                            LaneGroup.DemandVolumeVehPerHrSplit[1] = demandVolumesThru[travelDirectionIndex];
                            LaneGroup.DemandVolumeVehPerHrSplit[2] = demandVolumesRight[travelDirectionIndex];
                        }
                        LaneGroup.AnalysisFlowRate = LaneGroup.CalcAnalysisFlowRate(LaneGroup.DemandVolumeVehPerHr, LaneGroup.PeakHourFactor);
                    }
                }
            }
        }
Esempio n. 5
0
        private void btnCreateArterial_Click(object sender, EventArgs e)
        {
            Project = new ProjectData();
            //ArterialData newArterial = CreateArterial.NewArterial();

            //Art = CreateArterial2.NewArterial();
            Art = CreateArterial_HCMExample1.NewArterial(Project.AnalMode, 800);

            //Change file path/name as appropriate
            //Project.FileName = @"X:\OneDrive\Software Projects\HCM-CALC\_DataFiles\HCM\Urban Streets\HCMExample1.xml";
            //Project.FileName = @"C:\Users\Christian\source\repos\HCMCalc_UrbanStreets\bin\Output\HCMExample1.xml";
            if (OutputFilesFolder == "")
            {
                Project.FileName = "HCMExample1.xml";
            }
            else
            {
                Project.FileName = OutputFilesFolder + "\\HCMExample1.xml";
            }
            FileInputOutput2.SerializeArterialData(Project.FileName, Art);
        }
        /// <summary>
        /// Reverses an arterial's direction by reversing the segments and access points lists, then manually changing their speeds, length, and access points locations.
        /// </summary>
        /// <param name="Arterial"></param>
        public static void ReverseArterial(ref ArterialData Arterial)
        {
            Arterial.Segments.Reverse();
            for (int segmentIndex = Arterial.Segments.Count - 1; segmentIndex >= 0; segmentIndex--)
            {
                if (segmentIndex == 0)
                {
                    Arterial.Segments[segmentIndex].Link.LengthFt = 0;
                    Arterial.Segments[segmentIndex].LengthFt      = 0;
                }
                else
                {
                    Arterial.Segments[segmentIndex].Link.LengthFt     = Arterial.Segments[segmentIndex - 1].Link.LengthFt;
                    Arterial.Segments[segmentIndex].LengthFt          = Arterial.Segments[segmentIndex - 1].LengthFt;
                    Arterial.Segments[segmentIndex].Link.PostSpeedMPH = Arterial.Segments[segmentIndex - 1].Link.PostSpeedMPH;
                }

                Arterial.Segments[segmentIndex].Link.AccessPoints.Reverse();
                foreach (AccessPointData AccessPoint in Arterial.Segments[segmentIndex].Link.AccessPoints)
                {
                    AccessPoint.Location = 1 - AccessPoint.Location;
                }
            }
        }
Esempio n. 7
0
        public void WriteXmlFile(string filename, bool previewMode, ProjectData Project, ArterialData Art, List <IntersectionData> Int, List <LinkData> Seg, ServiceVolumes SerVol, bool overVCMessage, bool writeResults)
        {
            XmlTextWriter xtw = new XmlTextWriter(filename, System.Text.Encoding.UTF8);

            //indent tags by 2 characters
            xtw.Formatting  = Formatting.Indented;
            xtw.Indentation = 2;
            //enclose attributes' values in float quotes
            xtw.QuoteChar = '"';
            xtw.WriteStartDocument(true);
            if (previewMode == true)
            {
                string XSLfileName     = XSLfileName = Application.StartupPath + "\\APauto1.xsl";
                string InstructionText = "type=\"text/xsl\" href=\"" + XSLfileName + "\"";
                xtw.WriteProcessingInstruction("xml-stylesheet", InstructionText);
            }
            //write <TMML> information
            xtw.WriteStartElement("TMML");
            xtw.WriteAttributeString("Facility", "Arterial");
            //write <PROJECT> information
            xtw.WriteStartElement("PROJECT");
            xtw.WriteElementString("FileName", Project.FileName);  //("FileName", filename)
            xtw.WriteElementString("Analyst", Project.AnalystName);
            xtw.WriteElementString("Date", Project.AnalysisDate.ToString());
            xtw.WriteElementString("Agency", Project.Agency);
            xtw.WriteElementString("Comment", Project.UserNotes);

            if (Project.Mode == ModeType.AutoOnly)
            {
                xtw.WriteElementString("ModalAnalysis", "Auto Only");
            }
            else if (Project.Mode == ModeType.SignalOnly)
            {
                xtw.WriteElementString("ModalAnalysis", "Isolated Signal");
            }

            if (Project.DirectionAnalysisMode == DirectionType.PeakDirection)
            {
                xtw.WriteElementString("AnalysisType", "Peak Direction");
            }
            else if (Project.DirectionAnalysisMode == DirectionType.BothDirections)
            {
                xtw.WriteElementString("AnalysisType", "Peak and Off-Peak Directions");
            }

            if (Project.Period == StudyPeriod.StandardK)
            {
                xtw.WriteElementString("PeriodID", "Standard K");
            }
            else if (Project.Period == StudyPeriod.Kother)
            {
                xtw.WriteElementString("PeriodID", "Kother");
            }
            else if (Project.Period == StudyPeriod.PeakHour)
            {
                xtw.WriteElementString("PeriodID", "Dir Hr Demand Vol");
            }

            xtw.WriteElementString("Program", "ARTPLAN 2012");
            xtw.WriteElementString("Version", FDOTplanning_ParmRanges.VersionDate);

            xtw.WriteEndElement();  //close the <PROJECT> tag

            //write <AnalysisParamters> information
            //** maybe not include since this information is never used (maybe by HCS)

            //write <ARTERIAL> information
            xtw.WriteStartElement("ARTERIAL");
            xtw.WriteAttributeString("id", "1");
            //write <ARTERIALINFO> information
            xtw.WriteStartElement("ARTERIALINFO");
            xtw.WriteElementString("ArterialName", Art.ArtName);
            xtw.WriteElementString("From", Art.From);
            xtw.WriteElementString("To", Art.To);

            if (Art.AnalysisTravelDir == TravelDirection.Northbound)
            {
                xtw.WriteElementString("FwdDirection", "Northbound");
            }
            else if (Art.AnalysisTravelDir == TravelDirection.Southbound)
            {
                xtw.WriteElementString("FwdDirection", "Southbound");
            }
            else if (Art.AnalysisTravelDir == TravelDirection.Westbound)
            {
                xtw.WriteElementString("FwdDirection", "Westbound");
            }
            else if (Art.AnalysisTravelDir == TravelDirection.Eastbound)
            {
                xtw.WriteElementString("FwdDirection", "Eastbound");
            }

            if (Art.Area == AreaType.LargeUrbanized)
            {
                xtw.WriteElementString("AreaType", "Large Urbanized");
            }
            else if (Art.Area == AreaType.OtherUrbanized)
            {
                xtw.WriteElementString("AreaType", "Other Urbanized");
            }
            else if (Art.Area == AreaType.Transitioning)
            {
                xtw.WriteElementString("AreaType", "Transitioning/Urban");
            }
            else if (Art.Area == AreaType.RuralDeveloped)
            {
                xtw.WriteElementString("AreaType", "Rural Developed");
            }

            xtw.WriteElementString("ArterialClass_HCM", Art.Classification.ToString());
            xtw.WriteElementString("KFactor_PLN", Art.Kfactor.ToString());
            xtw.WriteElementString("DFactor_PLN", Art.Dfactor.ToString());
            //xtw.WriteElementString("PHF", Art.PHF.ToString());
            //xtw.WriteElementString("BaseSatFlowPerLane", Art.Segments[0].Intersection.Approaches[0].LaneGroups[0].BaseSaturationFlowRate.ToString());
            xtw.WriteElementString("NumberOfIntersections", Convert.ToString(Art.TotalInts - 1));
            if (Project.Mode != ModeType.SignalOnly)
            {
                xtw.WriteElementString("ArtLength", Art.LengthMiles.ToString("0.0000"));
            }
            else
            {
                xtw.WriteElementString("ArtLength", "N/A");
            }
            xtw.WriteElementString("MaxSerVol", Art.MaxSerVol.ToString());
            xtw.WriteEndElement();  //close the <ARTERIALINFO> tag

            //write <APPROACH> information
            xtw.WriteStartElement("ARTERIALDIR");
            xtw.WriteAttributeString("id", "forward");
            //xtw.WriteElementString("NumberOfLanes", Art.);
            //xtw.WriteElementString("HVPct", Art.PctHeavyVeh.ToString());

            //only write results to file if results are currently displayed
            if (writeResults == true)
            {
                //write <MOEGROUP> information
                xtw.WriteStartElement("MOEGROUP");
                if (Project.Mode != ModeType.SignalOnly)
                {
                    xtw.WriteElementString("TotalTravelTime", Art.Results.TravelTime.ToString("0.00"));
                    //if (Art.WtdgC <= 0.50)
                    //    xtw.WriteElementString("WtdgC", Art.WtdgC.ToString("0.00"));
                    //else
                    //    xtw.WriteElementString("WtdgC", "##");
                    //xtw.WriteElementString("FFSDelay", Art.Results.FFSdelay.ToString("0.00"));
                    //xtw.WriteElementString("ThresholdDelay", Art.Results.ThreshDelay.ToString("0.00"));
                    if (overVCMessage == false)
                    {
                        xtw.WriteElementString("AvgTravelSpeed", Art.Results.AverageSpeed.ToString("0.00"));
                        //xtw.WriteElementString("BaseFreeFlowSpeed", Art.Results.BaseFreeFlowSpeed.ToString("0.00"));
                        xtw.WriteElementString("ArtLOS", Art.Results.LOS.ToString());
                    }
                    else
                    {
                        xtw.WriteElementString("AvgTravelSpeed", "###");
                        xtw.WriteElementString("BaseFreeFlowSpeed", "###");
                        xtw.WriteElementString("ArtLOS", "###");
                    }
                }
                else  //signal only
                {
                    xtw.WriteElementString("TotalTravelTime", "N/A");
                    xtw.WriteElementString("WtdgC", "N/A");
                    xtw.WriteElementString("AvgTravelSpeed", "N/A");
                    xtw.WriteElementString("FFSDelay", "N/A");
                    xtw.WriteElementString("ThresholdDelay", "N/A");
                    xtw.WriteElementString("ArtLOS", "N/A");
                }
                xtw.WriteEndElement();  //close the <MOEGROUP> tag
            }

            xtw.WriteEndElement();  //close the <APPROACH> tag

            if (Project.DirectionAnalysisMode == DirectionType.BothDirections)
            {
                //write <APPROACH> information
                xtw.WriteStartElement("APPROACH");
                xtw.WriteAttributeString("id", "reverse");
                //xtw.WriteElementString("NumberOfLanes", Art.);
                //xtw.WriteElementString("HVPct", Art[1].PctHeavyVeh.ToString());

                //write <MOEGROUP> information
                //xtw.WriteStartElement("MOEGROUP");

                xtw.WriteEndElement();  //close the <Approach> tag
            }

            //write <INTERSECTIONS> information
            xtw.WriteStartElement("INTERSECTIONS");
            for (int id = 1; id <= Art.TotalInts; id++)
            {
                //write a new <INTERSECTION id="nnn"> element
                xtw.WriteStartElement("INTERSECTION");
                xtw.WriteAttributeString("id", id.ToString());

                //write <INTERSECTIONINFO> information
                xtw.WriteStartElement("INTERSECTIONINFO");
                xtw.WriteElementString("CrossStreetName", Int[id].CrossStreetName);
                xtw.WriteEndElement();  //close the <INTERSECTIONINFO> tag

                //write <CONTROLLER> information
                xtw.WriteStartElement("CONTROLLER");
                //if (Art.SigControl == SigControlType.Pretimed)
                //    xtw.WriteElementString("ControlMode", "Pretimed");
                //else if (Art.SigControl == SigControlType.CoordinatedActuated)
                //    xtw.WriteElementString("ControlMode", "CoordinatedActuated");
                //else if (Art.SigControl == SigControlType.FullyActuated)
                //    xtw.WriteElementString("ControlMode", "FullyActuated");
                //xtw.WriteElementString("CycleLength", Int[id].CycleLen.ToString());
                //if (Int[id].LTphasing == PhasingType.Protect)
                //    xtw.WriteElementString("LeftTurnPhasing", "Protected");
                //else if (Int[id].LTphasing == PhasingType.ProtPerm)
                //    xtw.WriteElementString("LeftTurnPhasing", "ProtPerm");
                //else
                //    xtw.WriteElementString("LeftTurnPhasing", "None");
                xtw.WriteEndElement();                                                       //close the <CONTROLLER> tag

                if (id == 1 && Project.DirectionAnalysisMode == DirectionType.PeakDirection) // && Project.Mode != ModeType.SignalOnly)  //if peak direction analysis and not signal-only analysis, do not write remaining items for 1st intersection
                {
                    xtw.WriteEndElement();                                                   //close the <INTERSECTION> tag
                    continue;
                }

                //write <APPROACH> information
                xtw.WriteStartElement("APPROACH");
                xtw.WriteAttributeString("id", "forward");

                //write <LANEGROUP> information
                xtw.WriteStartElement("LANEGROUP");     //do not include id info, as all lane group info is currently grouped together

                xtw.WriteElementString("Section", Convert.ToString(id - 1));
                //Intersection Data
                //unit extension
                //xtw.WriteElementString("GCRatio", Int[id].gCthru.ToString());
                //if (Int[id].isLTbay == true)
                //{
                //    xtw.WriteElementString("LeftTurnBayYN", "Yes");
                //    xtw.WriteElementString("NumberLTlanes", Int[id].NumLTlanes.ToString());
                //    xtw.WriteElementString("LTBayLength", Int[id].LTbayLen.ToString());
                //    xtw.WriteElementString("GCRatioLT", Int[id].gClt.ToString("0.00"));
                //}
                //else  //false
                //{
                //    xtw.WriteElementString("LeftTurnBayYN", "No");
                //    xtw.WriteElementString("NumberLTlanes", "N/A");
                //    xtw.WriteElementString("LTBayLength", "N/A");
                //    xtw.WriteElementString("GCRatioLT", "N/A");
                //}

                //if (Int[id].isRTbay == true)
                //    xtw.WriteElementString("RightTurnBayYN", "Yes");
                //else  //false
                //    xtw.WriteElementString("RightTurnBayYN", "No");
                //xtw.WriteElementString("PctTurn_Left", Int[id].PctLT.ToString());
                //xtw.WriteElementString("PctTurn_Right", Int[id].PctRT.ToString());
                //xtw.WriteElementString("ArrivalType", Int[id].ArvType.ToString());
                //xtw.WriteElementString("NumberOfLanes_INT", Int[id].NumThLanes.ToString());
                //Segment Data
                //float SegLengthMiles = Convert.ToDouble(Seg[id - 1].Length) / 5280;
                if (Project.Mode != ModeType.SignalOnly)
                {
                    xtw.WriteElementString("LinkLength", Seg[id - 1].LengthFt.ToString());
                    xtw.WriteElementString("NumberOfLanes_SEG", Seg[id - 1].NumLanes.ToString());
                    xtw.WriteElementString("PostedSpeed", Seg[id - 1].PostSpeedMPH.ToString());
                    xtw.WriteElementString("FreeFlowSpeed", Seg[id - 1].Results.FreeFlowSpeedMPH.ToString());
                    if (Seg[id - 1].MedType == MedianType.None)
                    {
                        xtw.WriteElementString("MedianType", "None");
                    }
                    else if (Seg[id - 1].MedType == MedianType.Nonrestrictive)
                    {
                        xtw.WriteElementString("MedianType", "Non-Restrictive");
                    }
                    else if (Seg[id - 1].MedType == MedianType.Restrictive)
                    {
                        xtw.WriteElementString("MedianType", "Restrictive");
                    }

                    if (Seg[id - 1].OnStreetParkingExists == false)
                    {
                        xtw.WriteElementString("OnStreetParkingYN", "No");
                    }
                    else  //true
                    {
                        xtw.WriteElementString("OnStreetParkingYN", "Yes");
                    }

                    if (Seg[id - 1].ParkingActivity == ParkingActivityLevel.Low)
                    {
                        xtw.WriteElementString("ParkingActivity", "Low");
                    }
                    else if (Seg[id - 1].ParkingActivity == ParkingActivityLevel.Medium)
                    {
                        xtw.WriteElementString("ParkingActivity", "Medium");
                    }
                    else if (Seg[id - 1].ParkingActivity == ParkingActivityLevel.High)
                    {
                        xtw.WriteElementString("ParkingActivity", "High");
                    }
                    else if (Seg[id - 1].ParkingActivity == ParkingActivityLevel.NotApplicable)
                    {
                        xtw.WriteElementString("ParkingActivity", "N/A");
                    }
                }
                else
                {
                    xtw.WriteElementString("LinkLength", "N/A");
                    xtw.WriteElementString("NumberOfLanes_SEG", "N/A");
                    xtw.WriteElementString("FreeFlowSpeed", "N/A");
                    xtw.WriteElementString("MedianType", "N/A");
                }

                xtw.WriteElementString("AADT", Seg[id - 1].AADT.ToString());
                xtw.WriteElementString("DDHV", Seg[id - 1].DDHV.ToString("0"));
                //Calculated Values
                //xtw.WriteElementString("ThruMvmtFlowRate", Int[id].ThruVol.ToString("0"));
                //xtw.WriteElementString("AdjSatFlowRate", (Int[id].AdjSatFlow * Int[id].NumThLanes).ToString("0"));
                //xtw.WriteElementString("Cap", Int[id].Capacity.ToString("0"));

                if (Seg[id - 1].OutsideLaneWidth == OutLaneWidth.Narrow)
                {
                    xtw.WriteElementString("OutsideLnWidth", "Narrow");
                }
                else if (Seg[id - 1].OutsideLaneWidth == OutLaneWidth.Typical)
                {
                    xtw.WriteElementString("OutsideLnWidth", "Typical");
                }
                else if (Seg[id - 1].OutsideLaneWidth == OutLaneWidth.Wide)
                {
                    xtw.WriteElementString("OutsideLnWidth", "Wide");
                }
                //else if (Seg[id - 1].OutsideLaneWidth == OutLaneWidth.Custom)
                //    xtw.WriteElementString("OutsideLnWidth", Seg[id - 1].NumOutsideLaneWidth.ToString());

                //if (Seg[id - 1].PaveCond == PavementCondition.Desirable)
                //    xtw.WriteElementString("PavementCondition", "Desirable");
                //else if (Seg[id - 1].PaveCond == PavementCondition.Typical)
                //    xtw.WriteElementString("PavementCondition", "Typical");
                //else if (Seg[id - 1].PaveCond == PavementCondition.Undesirable)
                //    xtw.WriteElementString("PavementCondition", "Undesirable");

                //if (Seg[id - 1].BikeLaneExists == false)
                //    xtw.WriteElementString("BikeLnYN", "No");
                //else  //true
                //    xtw.WriteElementString("BikeLnYN", "Yes");

                //if (Seg[id - 1].SidewalkExists == false)
                //    xtw.WriteElementString("SidewalkYN", "No");
                //else  //true
                //    xtw.WriteElementString("SidewalkYN", "Yes");


                //only write results to file if results are currently displayed
                if (writeResults == true)
                {
                    //write <MOEGROUP> information
                    //xtw.WriteStartElement("MOEGROUP");
                    if (Project.Mode != ModeType.SignalOnly)
                    {
                        xtw.WriteElementString("VCRatio", Int[id].Results.vcRatio.ToString("0.000"));
                        xtw.WriteElementString("ControlDelay", Int[id].Results.ControlDelay.ToString("0.00"));
                        xtw.WriteElementString("IntLOS", Int[id].Results.LOS);
                        //if (Int[id].Approaches[0].LaneGroups[0].AnalysisResults.QueStorageRatio <= 1.0)
                        //    xtw.WriteElementString("QueueStorageRatio", Int[id].Results.QueStorageRatio.ToString("0.00"));
                        //else
                        //    xtw.WriteElementString("QueueStorageRatio", "#");
                        xtw.WriteElementString("BaseFreeFlowSpeed", Seg[id - 1].Results.BaseFreeFlowSpeed.ToString("0.00"));
                        //xtw.WriteElementString("SectAverageTravelSpeed", Seg[id - 1].Results.AverageSpeed.ToString("0.00"));
                        xtw.WriteElementString("SectLOS", Seg[id - 1].Results.LOS);
                    }
                    else  //signal-only analysis
                    {
                        xtw.WriteElementString("VCRatio", Int[2].Results.vcRatio.ToString("0.000"));
                        xtw.WriteElementString("ControlDelay", Int[2].Results.ControlDelay.ToString("0.00"));
                        xtw.WriteElementString("IntLOS", Int[2].Results.LOS);
                        //if (Int[2].Results.QueStorageRatio <= 1.0)
                        //    xtw.WriteElementString("QueueStorageRatio", Int[2].Results.QueStorageRatio.ToString("0.00"));
                        //else
                        //    xtw.WriteElementString("QueueStorageRatio", "#");
                        xtw.WriteElementString("BaseFreeFlowSpeed", "N/A");
                        xtw.WriteElementString("SectAverageTravelSpeed", "N/A");
                        xtw.WriteElementString("SectLOS", "N/A");
                    }
                    //xtw.WriteEndElement();  //close the <MOEGROUP> tag
                }

                xtw.WriteEndElement(); //close the <LANEGROUP> tag

                xtw.WriteEndElement(); //close the <APPROACH> tag
                xtw.WriteEndElement(); //close the <INTERSECTION> tag
            }
            xtw.WriteEndElement();     //close the <INTERSECTIONS> tag

            //only write service volume tables to file if results are currently displayed
            bool WriteServiceVols = false; //temp

            if (WriteServiceVols == true)  //(writeResults == true)
            {
                xtw.WriteStartElement("LOSTABLES");
                xtw.WriteAttributeString("Mode", "Auto");

                for (int lanes = 1; lanes <= 5; lanes++)      //2,4,6,8,*
                {
                    xtw.WriteStartElement("CROSSSECTION");
                    xtw.WriteAttributeString("Lanes", (lanes * 2).ToString());

                    for (int LOS = 1; LOS <= 5; LOS++)      //LOS A-E
                    {
                        xtw.WriteStartElement("SERVICEVOL");
                        xtw.WriteAttributeString("LOS", LOS.ToString());

                        if (SerVol.PkDirVol[lanes, LOS] > 0)
                        {
                            xtw.WriteElementString("PeakDirection", SerVol.PkDirVol[lanes, LOS].ToString());
                            if (Project.Period != StudyPeriod.PeakHour)     // Dir Pk Hr Demand study period
                            {
                                xtw.WriteElementString("BothDirections", SerVol.BothDirVol[lanes, LOS].ToString());
                                xtw.WriteElementString("AADT", SerVol.AADT[lanes, LOS].ToString());
                            }
                            else
                            {
                                xtw.WriteElementString("BothDirections", "N/A");
                                xtw.WriteElementString("AADT", "N/A");
                            }
                        }
                        else if (SerVol.PkDirVol[lanes, LOS] == -2)
                        {
                            xtw.WriteElementString("PeakDirection", "**");
                            if (Project.Period != StudyPeriod.PeakHour)     // Dir Pk Hr Demand study period
                            {
                                xtw.WriteElementString("BothDirections", "**");
                                xtw.WriteElementString("AADT", "**");
                            }
                            else
                            {
                                xtw.WriteElementString("BothDirections", "N/A");
                                xtw.WriteElementString("AADT", "N/A");
                            }
                        }
                        else if (SerVol.PkDirVol[lanes, LOS] == -3)
                        {
                            xtw.WriteElementString("PeakDirection", "***");
                            if (Project.Period != StudyPeriod.PeakHour)     // Dir Pk Hr Demand study period
                            {
                                xtw.WriteElementString("BothDirections", "***");
                                xtw.WriteElementString("AADT", "***");
                            }
                            else
                            {
                                xtw.WriteElementString("BothDirections", "N/A");
                                xtw.WriteElementString("AADT", "N/A");
                            }
                        }
                        xtw.WriteEndElement(); //close the <SERVICEVOL> tag
                    }
                    xtw.WriteEndElement();     //close the <CROSSSECTION> tag
                }
                xtw.WriteEndElement();         //close the <LOSTABLES> tag
            }

            xtw.WriteEndElement();  //close the <ARTERIAL> tag
            xtw.WriteEndDocument(); //close the <TMML> tag
            xtw.Close();
        }
Esempio n. 8
0
        // Illegal XML characters: < (less than), > (greater than), & (ampersand), ' (apostrophe), " (quotation mark)

        public void ReadXmlFile(string filename, ProjectData project, ArterialData Art, List <IntersectionData> ints, List <LinkData> segs)
        {
            XmlTextReader xtr   = new XmlTextReader(filename);
            int           Index = 0;                          //index for intersection number
            //int SubSegNum = 0;  //index for ped subsegment number
            int TotInts = 1;                                  //total number of intersections

            IntersectionData newInt = new IntersectionData(); // (Art.Area, Art.Classification, Art.SigControl);  //first intersection is "dummy" intersection

            ints.Add(newInt);

            LinkData newSeg = new LinkData();  // (Art.Area, Art.Classification);    //first segment is "dummy" segment

            segs.Add(newSeg);

            while (xtr.Read())
            {
                if (xtr.NodeType == XmlNodeType.Whitespace)
                {
                    continue;
                }

                if (xtr.IsStartElement("PROJECT"))
                {
                    while (xtr.Read())
                    {
                        if (xtr.NodeType == XmlNodeType.EndElement)
                        {
                            if (xtr.Name == "PROJECT")
                            {
                                break;
                            }
                        }

                        switch (xtr.Name)
                        {
                        //Project Data Elements
                        case "FileName":
                            break;

                        case "Analyst":
                            project.AnalystName = xtr.ReadElementContentAsString();
                            break;

                        case "Date":
                            //project.AnalDate = xtr.ReadElementContentAsDateTime();
                            project.AnalysisDate = Convert.ToDateTime(xtr.ReadElementContentAsString());
                            break;

                        case "Agency":
                            project.Agency = xtr.ReadElementContentAsString();
                            break;

                        case "AgencyName":      //for compatibality with Artplan 2007 files
                            project.Agency = xtr.ReadElementContentAsString();
                            break;

                        case "Comment":
                            project.UserNotes = xtr.ReadElementContentAsString();
                            break;

                        case "PeriodID":
                            string period = xtr.ReadElementContentAsString();
                            if (period == "Standard K" || period == "K100")
                            {
                                project.Period = StudyPeriod.StandardK;
                            }
                            else if (period == "Kother")
                            {
                                project.Period = StudyPeriod.Kother;
                            }
                            else if (period == "Dir Hr Demand Vol")
                            {
                                project.Period = StudyPeriod.PeakHour;
                            }
                            break;

                        case "AnalysisType":
                            string AnalType = xtr.ReadElementContentAsString();
                            if (AnalType == "Peak Direction")
                            {
                                project.DirectionAnalysisMode = DirectionType.PeakDirection;
                            }
                            else if (AnalType == "Peak and Off-Peak Directions")
                            {
                                project.DirectionAnalysisMode = DirectionType.BothDirections;
                            }
                            break;

                        case "ModalAnalysis":
                            string Mode = xtr.ReadElementContentAsString();
                            if (Mode == "Multimodal")
                            {
                                project.Mode = ModeType.Multimodal;
                            }
                            else if (Mode == "Auto Only")
                            {
                                project.Mode = ModeType.AutoOnly;
                            }
                            else if (Mode == "Isolated Signal")
                            {
                                project.Mode = ModeType.SignalOnly;
                            }
                            break;

                        case "MultiModal":      //for compatibality with Artplan 2007 files
                            string Mode2 = xtr.ReadElementContentAsString();
                            if (Mode2 == "True")
                            {
                                project.Mode = ModeType.Multimodal;
                            }
                            else
                            {
                                project.Mode = ModeType.AutoOnly;
                            }
                            //signal only analysis was handled through Class field in Artplan 2007
                            //signal only analysis files are not handled because all the inputs were handled through the general facility data screen (i.e., ArterialInfo), which no longer exists
                            break;
                        }
                    }
                }
                else if (xtr.IsStartElement("ARTERIALINFO"))
                {
                    while (xtr.Read())
                    {
                        if (xtr.NodeType == XmlNodeType.EndElement)
                        {
                            if (xtr.Name == "ARTERIALINFO")
                            {
                                break;
                            }
                        }

                        switch (xtr.Name)
                        {
                        //Arterial Values
                        case "ArterialName":
                            Art.ArtName = xtr.ReadElementContentAsString();
                            break;

                        case "From":
                            Art.From = xtr.ReadElementContentAsString();
                            break;

                        case "To":
                            Art.To = xtr.ReadElementContentAsString();
                            break;

                        case "FwdDirection":
                            string peakDir = xtr.ReadElementContentAsString();
                            if (peakDir == "Northbound")
                            {
                                Art.AnalysisTravelDir = TravelDirection.Northbound;
                            }
                            else if (peakDir == "Southbound")
                            {
                                Art.AnalysisTravelDir = TravelDirection.Southbound;
                            }
                            else if (peakDir == "Eastbound")
                            {
                                Art.AnalysisTravelDir = TravelDirection.Eastbound;
                            }
                            else if (peakDir == "Westbound")
                            {
                                Art.AnalysisTravelDir = TravelDirection.Westbound;
                            }
                            break;

                        case "AreaType":
                            string areaType = xtr.ReadElementContentAsString();
                            if (areaType == "Large Urbanized")
                            {
                                Art.Area = AreaType.LargeUrbanized;
                            }
                            else if (areaType == "Other Urbanized")
                            {
                                Art.Area = AreaType.OtherUrbanized;
                            }
                            else if (areaType == "Transitioning/Urban")
                            {
                                Art.Area = AreaType.Transitioning;
                            }
                            else if (areaType == "Rural Developed")
                            {
                                Art.Area = AreaType.RuralDeveloped;
                            }
                            break;

                        case "ArterialClass_HCM":
                            Art.Classification = (ArterialClass)xtr.ReadElementContentAsInt();
                            if ((int)Art.Classification > 2)       //code to handle legacy projects that used 4 classes
                            {
                                Art.Classification = ArterialClass.ClassII;
                            }
                            break;

                        case "ArtLength":
                            Art.LengthMiles = xtr.ReadElementContentAsFloat();
                            break;

                        case "KFactor_PLN":
                            Art.Kfactor = xtr.ReadElementContentAsFloat();
                            break;

                        case "DFactor_PLN":
                            Art.Dfactor = xtr.ReadElementContentAsFloat();
                            break;

                        case "PHF":
                            //Art.PHF = xtr.ReadElementContentAsFloat();
                            break;

                        case "BaseSatFlowPerLane":
                            //Art.BaseSatFlow = xtr.ReadElementContentAsInt();
                            break;

                        case "NumberOfIntersections":
                            TotInts = xtr.ReadElementContentAsInt();
                            break;
                        }
                    }
                }

                else if (xtr.IsStartElement("ARTERIALDIR")) // || xtr.IsStartElement("APPROACH")) //The 'APPROACH ' tag is to provide support to Artplan 2007 version
                {
                    while (xtr.Read())
                    {
                        if (xtr.NodeType == XmlNodeType.EndElement)
                        {
                            if (xtr.Name == "ARTERIALDIR") // || xtr.Name == "APPROACH")
                            {
                                break;
                            }
                        }

                        switch (xtr.Name)
                        {
                        //Direction specific approach items
                        case "HVPct":
                            //Art.PctHeavyVeh = xtr.ReadElementContentAsFloat();
                            break;
                        }
                    }
                }

                else if (xtr.IsStartElement("INTERSECTIONINFO"))
                {
                    while (xtr.Read())
                    {
                        if (xtr.NodeType == XmlNodeType.EndElement)
                        {
                            if (xtr.Name == "INTERSECTIONINFO")
                            {
                                break;
                            }
                        }

                        newInt = new IntersectionData(1, Art.Area, Art.Classification, null, new SignalCycleData());
                        ints.Add(newInt);
                        newSeg = new LinkData();
                        segs.Add(newSeg);

                        switch (xtr.Name)
                        {
                        //Intersection Data Elements
                        case "CrossStreetName":
                            Index++;        //increment intersection counter
                            ints[Index].CrossStreetName = xtr.ReadElementContentAsString();
                            break;
                        }
                    }
                }
                else if (xtr.IsStartElement("CONTROLLER"))
                {
                    while (xtr.Read())
                    {
                        if (xtr.NodeType == XmlNodeType.EndElement)
                        {
                            if (xtr.Name == "CONTROLLER")
                            {
                                break;
                            }
                        }

                        switch (xtr.Name)
                        {
                        case "ControlMode":
                            string controlMode = xtr.ReadElementContentAsString();
                            //if (controlMode == "Pretimed")
                            //    Art.SigControl = SigControlType.Pretimed;
                            //else if (controlMode == "CoordinatedActuated")
                            //    Art.SigControl = SigControlType.CoordinatedActuated;
                            //else if (controlMode == "FullyActuated")
                            //    Art.SigControl = SigControlType.FullyActuated;
                            break;

                        case "CycleLength":
                            //ints[Index].CycleLen = xtr.ReadElementContentAsInt();
                            break;

                        case "LeftTurnPhasing":
                            string LTphasing = xtr.ReadElementContentAsString();
                            //if (LTphasing == "Protected")
                            //    ints[Index].LTphasing = PhasingType.Protect;
                            //else if (LTphasing == "ProtPerm")
                            //    ints[Index].LTphasing = PhasingType.ProtPerm;
                            //else
                            //    ints[Index].LTphasing = PhasingType.None;
                            break;
                        }
                    }
                }
                else if (xtr.IsStartElement("LANEGROUP"))
                {
                    while (xtr.Read())
                    {
                        if (xtr.NodeType == XmlNodeType.EndElement)
                        {
                            if (xtr.Name == "LANEGROUP")
                            {
                                //SubSegNum = 0;  //reset subsegment counter for next segment
                                break;
                            }
                        }

                        switch (xtr.Name)
                        {
                        case "GCRatio":
                            ints[Index].Approaches[0].LaneGroups[0].SignalPhase.gC = xtr.ReadElementContentAsFloat();
                            break;

                        case "LeftTurnBayYN":
                            string LTBay = xtr.ReadElementContentAsString();
                            //if (LTBay == "No")
                            //    ints[Index].isLTbay = false;
                            //else
                            //    ints[Index].isLTbay = true;
                            break;

                        case "NumberLTlanes":
                            string LTlanes = xtr.ReadElementContentAsString();
                            //if (LTlanes != "N/A")
                            //    ints[Index].NumLTlanes = Convert.ToInt32(LTlanes);
                            break;

                        case "LTBayLength":
                            string LTbayLen = xtr.ReadElementContentAsString();
                            //if (LTbayLen != "N/A")
                            //    ints[Index].LTbayLen = Convert.ToInt32(LTbayLen);
                            break;

                        case "GCRatioLT":
                            string LTgCratio = xtr.ReadElementContentAsString();
                            //if (LTgCratio != "N/A")
                            //    ints[Index].gClt = Convert.ToSingle(LTgCratio);
                            break;

                        case "RightTurnBayYN":
                            string RTBay = xtr.ReadElementContentAsString();
                            //if (RTBay == "No")
                            //    ints[Index].isRTbay = false;
                            //else
                            //    ints[Index].isRTbay = true;
                            break;

                        case "PctTurn_Left":
                            //ints[Index].PctLT = xtr.ReadElementContentAsInt();
                            break;

                        case "PctTurn_Right":
                            //nts[Index].PctRT = xtr.ReadElementContentAsInt();
                            break;

                        case "ArrivalType":
                            //ints[Index].ArvType = xtr.ReadElementContentAsInt();
                            break;

                        case "NumberOfLanes_INT":
                            //ints[Index].NumThLanes = xtr.ReadElementContentAsFloat();
                            break;

                        //Segment Data Elements
                        case "LinkLength":
                            //subtract 1 from index since there is one less segment than # of intersections
                            float SegLength = xtr.ReadElementContentAsFloat();
                            if (SegLength < 10)
                            {
                                segs[Index - 1].LengthFt = SegLength * 5280;
                            }
                            else
                            {
                                segs[Index - 1].LengthFt = SegLength;
                            }
                            break;

                        case "AADT":
                            segs[Index - 1].AADT = xtr.ReadElementContentAsLong();
                            break;

                        case "DDHV":
                            segs[Index - 1].DDHV = xtr.ReadElementContentAsFloat();
                            break;

                        case "NumberOfLanes_SEG":
                            segs[Index - 1].NumLanes = xtr.ReadElementContentAsInt();
                            break;

                        case "PostedSpeed":
                            segs[Index - 1].PostSpeedMPH = xtr.ReadElementContentAsInt();
                            break;

                        case "FreeFlowSpeed":
                            //segs[Index - 1].FFSpeed = xtr.ReadElementContentAsFloat();
                            break;

                        case "MedianType":
                            string MedType = xtr.ReadElementContentAsString();
                            if (MedType == "None")
                            {
                                segs[Index - 1].MedType = MedianType.None;
                            }
                            else if (MedType == "Non-Restrictive")
                            {
                                segs[Index - 1].MedType = MedianType.Nonrestrictive;
                            }
                            else if (MedType == "Restrictive")
                            {
                                segs[Index - 1].MedType = MedianType.Restrictive;
                            }
                            //SegNum++;
                            break;

                        case "OnStreetParkingYN":
                            string OnStreetParkingYN = xtr.ReadElementContentAsString();
                            if (OnStreetParkingYN == "No")
                            {
                                segs[Index - 1].OnStreetParkingExists = false;
                            }
                            else
                            {
                                segs[Index - 1].OnStreetParkingExists = true;
                            }
                            break;

                        case "ParkingActivity":
                            string ParkingActivity = xtr.ReadElementContentAsString();
                            if (ParkingActivity == "Low")
                            {
                                segs[Index - 1].ParkingActivity = ParkingActivityLevel.Low;
                            }
                            else if (ParkingActivity == "Medium")
                            {
                                segs[Index - 1].ParkingActivity = ParkingActivityLevel.Medium;
                            }
                            else if (ParkingActivity == "High")
                            {
                                segs[Index - 1].ParkingActivity = ParkingActivityLevel.High;
                            }
                            else      // N/A (on-street parking not present)
                            {
                                segs[Index - 1].ParkingActivity = ParkingActivityLevel.NotApplicable;
                            }
                            break;

                        //Multimodal Segment Data Elements
                        case "OutsideLnWidth":
                            string LaneWidth = xtr.ReadElementContentAsString();
                            if (LaneWidth == "Narrow")
                            {
                                segs[Index - 1].OutsideLaneWidth = OutLaneWidth.Narrow;
                            }
                            else if (LaneWidth == "Typical")
                            {
                                segs[Index - 1].OutsideLaneWidth = OutLaneWidth.Typical;
                            }
                            else if (LaneWidth == "Wide")
                            {
                                segs[Index - 1].OutsideLaneWidth = OutLaneWidth.Wide;
                            }
                            else      //custom
                            {
                                segs[Index - 1].OutsideLaneWidth = OutLaneWidth.Custom;
                                //Seg[Index - 1].NumOutsideLaneWidth = Convert.ToInt32(LaneWidth);
                            }
                            break;

                        case "PavementCondition":
                            string PaveCond = xtr.ReadElementContentAsString();
                            //if (PaveCond == "Desirable")
                            //    Seg[Index - 1].PaveCond = PavementCondition.Desirable;
                            //else if (PaveCond == "Typical")
                            //    Seg[Index - 1].PaveCond = PavementCondition.Typical;
                            //else if (PaveCond == "Undesirable")
                            //    Seg[Index - 1].PaveCond = PavementCondition.Undesirable;
                            break;

                        case "BikeLnYN":
                            string BikeLaneYN = xtr.ReadElementContentAsString();
                            //if (BikeLaneYN == "No")
                            //    SegMM[Index - 1].BikeLaneExists = false;
                            //else
                            //    SegMM[Index - 1].BikeLaneExists = true;
                            break;

                        case "SidewalkYN":
                            string SidewalkYN = xtr.ReadElementContentAsString();
                            //if (SidewalkYN == "No")
                            //    SegMM[Index - 1].SidewalkExists = false;
                            //else
                            //    SegMM[Index - 1].SidewalkExists = true;
                            break;
                        }
                    }
                }
            }

            /*
             * if (Index == TotInts + 1)
             * {
             *  xtr.Close();
             *  Art.TotalInts = Index;
             *  Art.TotalSegs = Index - 1;
             *  return;
             * }
             */
            Art.TotalInts = Index;
            Art.TotalSegs = Index - 1;
            xtr.Close();
        }
        /// <summary>
        /// Creates the Service Volumes for an arterial based on input parameters.
        /// </summary>
        /// <param name="Project"></param>
        /// <param name="SerVol"></param>
        /// <param name="inputsOneLane"></param>
        /// <param name="inputsMultiLane"></param>

        /*public static void ServiceVolsAuto(ProjectData Project, ServiceVolumes SerVol, ServiceVolumeArterialInputs
         * inputsOneLane, ServiceVolumeArterialInputs inputsMultiLane)
         * {
         *
         *  float NumberOfLoops = 5 * 5;  //This accounts for LOS and Lanes, does not account for volume increments; Type is float just to avoid extra cast in calculations below
         *  int LoopCounter = 0;
         *  frmMain.bgwRunServiceVolsCalcs.ReportProgress(0);
         *
         *  ArterialData Arterial = new ArterialData();
         *  for (int lanes = 0; lanes < 5; lanes++) // 2,4,6,8,*
         *  {
         *      int vol = 40; // Starting volume (volume entering upstream of first intersection)
         *      bool threshExceeded = false;
         *
         *      // Variable access points
         *
         *      ServiceVolumeArterialInputs inputsForArterialCreation = inputsOneLane;
         *      if (lanes > 0)
         *          inputsForArterialCreation = inputsMultiLane;
         *
         *      if (lanes != 4)
         *          Arterial = CreateArterial_FDOTSerVols.NewArterial(inputsForArterialCreation, vol, lanes + 1);
         *      else
         *          Arterial = CreateArterial_FDOTSerVols.NewArterial(inputsForArterialCreation, vol);
         *
         *      for (int LOSlevel = 0; LOSlevel < 5; LOSlevel++) // LOS A-E
         *      {
         *          LoopCounter++;
         *
         *          int[] ServiceVolsArray;
         *          do
         *          {
         *              CreateArterial_FDOTSerVols.ChangeArterialVolume(ref Arterial, vol);
         *              Arterial.TestSerVol = vol;
         *              CalcsArterial.CalcResults(Project, ref Arterial);
         *
         *              if (!Arterial.OverCapacity)
         *              {
         *                  // Check whether LOS speed threshold has been exceeded
         *                  if (Arterial.Results.AverageSpeed < Arterial.Thresholds.Speed[LOSlevel])  // Avg. speed below LOS threshold speed
         *                  {
         *                      vol -= 10;
         *                      threshExceeded = true;
         *                      if (vol <= 0)
         *                      {
         *                          vol = 10;
         *                          SerVol.PkDirVol[lanes, LOSlevel] = -1;
         *                          SerVol.BothDirVol[lanes, LOSlevel] = -1;
         *                          SerVol.AADT[lanes, LOSlevel] = -1;
         *                          SerVol.Found[lanes, LOSlevel] = true;
         *                      }
         *                  }
         *                  else
         *                  {
         *                      if (threshExceeded == false) // Threshold not exceeded, increment volume
         *                      {
         *                          if ((Arterial.Results.AverageSpeed - Arterial.Thresholds.Speed[LOSlevel]) > 5)
         *                              vol += (30 * (lanes + 1) * (LOSlevel + 1));
         *                          else
         *                              vol += 10;
         *                      }
         *                      else // Threshold exceeded, record volume for LOS level
         *                      {
         *                          if (LOSlevel > 0)
         *                              ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, SerVol.PkDirVol[lanes, LOSlevel - 1]);
         *                          else
         *                              ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, -1);
         *                          SerVol.PkDirVol[lanes, LOSlevel] = ServiceVolsArray[0];
         *                          SerVol.BothDirVol[lanes, LOSlevel] = ServiceVolsArray[1];
         *                          SerVol.AADT[lanes, LOSlevel] = ServiceVolsArray[2];
         *                          SerVol.Found[lanes, LOSlevel] = true;
         *                          vol += 10; // Increment volume for start of next LOS level
         *                          threshExceeded = false;
         *                      }
         *                  }
         *              }
         *              else  // Check to see if there is a constraining intersection due to (v/c * PHF) > 1
         *              {
         *                  vol -= 10; // Return to the previous non-capacity-constrained volume
         *                  for (int capCheckLOSlevel = LOSlevel + 1; capCheckLOSlevel < 5; capCheckLOSlevel++) // LOS A-E
         *                  {
         *                      SerVol.PkDirVol[lanes, capCheckLOSlevel] = -2;
         *                      SerVol.BothDirVol[lanes, capCheckLOSlevel] = -2;
         *                      SerVol.AADT[lanes, capCheckLOSlevel] = -2;
         *                      SerVol.Found[lanes, capCheckLOSlevel] = true;
         *                  }
         *                  if (LOSlevel > 0)
         *                      ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, SerVol.PkDirVol[lanes, LOSlevel - 1]);
         *                  else
         *                      ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, -1);
         *                  SerVol.PkDirVol[lanes, LOSlevel] = ServiceVolsArray[0];
         *                  SerVol.BothDirVol[lanes, LOSlevel] = ServiceVolsArray[1];
         *                  SerVol.AADT[lanes, LOSlevel] = ServiceVolsArray[2];
         *                  SerVol.Found[lanes, LOSlevel] = true;
         *              }
         *          }
         *          while (SerVol.Found[lanes, LOSlevel] == false);     //loop until service vol reached for given LOS
         *          if (Arterial.OverCapacity)
         *          {
         *              LoopCounter = 5 * (lanes + 1);
         *              frmMain.bgwRunServiceVolsCalcs.ReportProgress((int)(Math.Round(LoopCounter / NumberOfLoops * 100, 0, MidpointRounding.AwayFromZero)));
         *              break;
         *          }
         *          frmMain.bgwRunServiceVolsCalcs.ReportProgress((int)(Math.Round(LoopCounter / NumberOfLoops * 100, 0, MidpointRounding.AwayFromZero)));
         *      } // BP here to view service volumes by LOS
         *  } // BP here to view service volumes by number of lanes
         * } // BP here to view all service volumes*/

        public static void ServiceVolsAutoNew(ProjectData Project, ServiceVolumes SerVol, ServiceVolumeTableFDOT inputsOneLane, ServiceVolumeTableFDOT inputsMultiLane)
        {
            float NumberOfLoops = 5 * 5;  //This accounts for LOS and Lanes, does not account for volume increments; Type is float just to avoid extra cast in calculations below
            int   LoopCounter   = 0;

            frmMain.bgwRunServiceVolsCalcs.ReportProgress(0);

            ArterialData Arterial = new ArterialData();

            for (int lanes = 0; lanes < 5; lanes++) // 2,4,6,8,*
            {
                int  vol            = 40;           // Starting volume (volume entering upstream of first intersection)
                bool threshExceeded = false;

                // Variable access points

                ServiceVolumeTableFDOT inputsForArterialCreation = inputsOneLane;
                if (lanes > 0)
                {
                    inputsForArterialCreation = inputsMultiLane;
                }

                if (lanes != 4)
                {
                    Arterial = CreateArterial_FDOTSerVols.NewArterial(inputsForArterialCreation, Project.AnalMode, vol, lanes + 1);
                }
                else
                {
                    Arterial = CreateArterial_FDOTSerVols.NewArterial(inputsForArterialCreation, Project.AnalMode, vol);
                }

                for (int LOSlevel = 0; LOSlevel < 5; LOSlevel++) // LOS A-E
                {
                    LoopCounter++;

                    int[] ServiceVolsArray;
                    do
                    {
                        CreateArterial_FDOTSerVols.ChangeArterialVolume(ref Arterial, vol);
                        Arterial.TestSerVol = vol;
                        CalcsArterial.CalcResults(Project, ref Arterial);

                        if (!Arterial.OverCapacity)
                        {
                            // Check whether LOS speed threshold has been exceeded
                            if (Arterial.Results.AverageSpeed < Arterial.Thresholds.Speed[LOSlevel])  // Avg. speed below LOS threshold speed
                            {
                                vol           -= 10;
                                threshExceeded = true;
                                if (vol <= 0)
                                {
                                    vol = 10;
                                    SerVol.PkDirVol[lanes, LOSlevel]   = -1;
                                    SerVol.BothDirVol[lanes, LOSlevel] = -1;
                                    SerVol.AADT[lanes, LOSlevel]       = -1;
                                    SerVol.Found[lanes, LOSlevel]      = true;
                                }
                            }
                            else
                            {
                                if (threshExceeded == false) // Threshold not exceeded, increment volume
                                {
                                    if ((Arterial.Results.AverageSpeed - Arterial.Thresholds.Speed[LOSlevel]) > 5)
                                    {
                                        vol += (30 * (lanes + 1) * (LOSlevel + 1));
                                    }
                                    else
                                    {
                                        vol += 10;
                                    }
                                }
                                else // Threshold exceeded, record volume for LOS level
                                {
                                    //vol += 10;
                                    if (LOSlevel > 0)
                                    {
                                        ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, SerVol.PkDirVol[lanes, LOSlevel - 1]);
                                    }
                                    else
                                    {
                                        ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, -1);
                                    }
                                    SerVol.PkDirVol[lanes, LOSlevel]   = ServiceVolsArray[0];
                                    SerVol.BothDirVol[lanes, LOSlevel] = ServiceVolsArray[1];
                                    SerVol.AADT[lanes, LOSlevel]       = ServiceVolsArray[2];
                                    SerVol.Found[lanes, LOSlevel]      = true;
                                    vol           += 10; // Increment volume for start of next LOS level
                                    threshExceeded = false;
                                }
                            }
                        }
                        else  // Check to see if there is a constraining intersection due to (v/c * PHF) > 1
                        {
                            vol -= 10; // Return to the previous non-capacity-constrained volume
                            for (int capCheckLOSlevel = LOSlevel + 1; capCheckLOSlevel < 5; capCheckLOSlevel++) // LOS A-E
                            {
                                SerVol.PkDirVol[lanes, capCheckLOSlevel]   = -2;
                                SerVol.BothDirVol[lanes, capCheckLOSlevel] = -2;
                                SerVol.AADT[lanes, capCheckLOSlevel]       = -2;
                                SerVol.Found[lanes, capCheckLOSlevel]      = true;
                            }
                            if (LOSlevel > 0)
                            {
                                ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, SerVol.PkDirVol[lanes, LOSlevel - 1]);
                            }
                            else
                            {
                                ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, -1);
                            }
                            SerVol.PkDirVol[lanes, LOSlevel]   = ServiceVolsArray[0];
                            SerVol.BothDirVol[lanes, LOSlevel] = ServiceVolsArray[1];
                            SerVol.AADT[lanes, LOSlevel]       = ServiceVolsArray[2];
                            SerVol.Found[lanes, LOSlevel]      = true;
                        }
                    }while (SerVol.Found[lanes, LOSlevel] == false);     //loop until service vol reached for given LOS
                    threshExceeded = false;
                    if (Arterial.OverCapacity)
                    {
                        LoopCounter = 5 * (lanes + 1);
                        frmMain.bgwRunServiceVolsCalcs.ReportProgress((int)(Math.Round(LoopCounter / NumberOfLoops * 100, 0, MidpointRounding.AwayFromZero)));
                        break;
                    }
                    frmMain.bgwRunServiceVolsCalcs.ReportProgress((int)(Math.Round(LoopCounter / NumberOfLoops * 100, 0, MidpointRounding.AwayFromZero)));
                } // BP here to view service volumes by LOS
            }     // BP here to view service volumes by number of lanes
        }         // BP here to view all service volumes
        //public static bool LTMessage = false;
        /// <summary>
        /// Handles the assignment of arterial properties that require calculations and cannot be straightly assigned.
        /// </summary>
        /// <param name="Project"></param>
        /// <param name="Arterial"></param>
        public static void CalcResults(ProjectData Project, ref ArterialData Arterial /*, ref List<SegmentDataMM> SegMM*/)
        {
            float TotalLaneFeet = 0;
            float PrevVC        = 0;
            float AnalysisLaneGroupControlDelay = 0;

            Arterial.Results      = new ResultsArterialData();
            Arterial.OverCapacity = false;
            //CalcsBicycle.NumSidePathSegs = 0;

            OriginDestinationData ODdata = CalcsOriginDestination.DefineODmatrix(Arterial);

            foreach (SegmentDirection segDirection in Enum.GetValues(typeof(SegmentDirection)))
            {
                NemaMovementNumbers[] inputMovementsArray  = { NemaMovementNumbers.SBLeft, NemaMovementNumbers.EBThru, NemaMovementNumbers.NBThru };
                NemaMovementNumbers[] outputMovementsArray = { NemaMovementNumbers.EBLeft, NemaMovementNumbers.EBThru, NemaMovementNumbers.EBThru };
                if (segDirection == SegmentDirection.WBSB)
                {
                    ReverseArterial(ref Arterial);
                    inputMovementsArray  = new NemaMovementNumbers[] { NemaMovementNumbers.NBLeft, NemaMovementNumbers.WBThru, NemaMovementNumbers.SBThru }; // 3rd = SBR
                    outputMovementsArray = new NemaMovementNumbers[] { NemaMovementNumbers.WBLeft, NemaMovementNumbers.WBThru, NemaMovementNumbers.WBThru }; // 3rd = WBR
                }

                foreach (SegmentData segment in Arterial.Segments)
                {
                    segment.Results              = new ResultsSegmentData();
                    segment.Link.Results         = new ResultsLinkData(segment.Intersection.Signal.CycleLengthSec);
                    segment.Intersection.Results = new ResultsIntersectionData();

                    segment.Intersection.DemandVolumeVehPerHr = 0;
                    segment.Intersection.Results.ControlDelay = 0;
                    segment.Link.OutsideLaneWidth             = OutLaneWidth.Typical;
                    //segment.Link.Results.SpeedRatio = segment.Link.Results.AverageSpeed / segment.Link.Results.BaseFreeFlowSpeed;

                    if (Arterial.Segments.IndexOf(segment) > 0)
                    {
                        if (Project.AnalMode == AnalysisMode.Operations)
                        {
                            segment.Link.Results.BaseFreeFlowSpeed = SegmentCalcs.BaseFreeFlowSpeed(Project.AnalMode, Arterial.Area, segment.Link.PostSpeedMPH, segment.Link.NumLanes, segment.Link.LengthFt, segment.Link.MedType, segment.Link.PropRestrictMedian, segment.Link.PropCurbRightSide, segment.Link.PctOnStreetParking, segment.Link.AccessPoints.Count, segment.Link.AccessPoints.Count);
                            segment.Link.Results.FreeFlowSpeedMPH  = SegmentCalcs.FreeFlowSpeed(segment.Link.Results.BaseFreeFlowSpeed, segment.LengthFt);
                        }
                        else
                        {
                            segment.Link.Results.BaseFreeFlowSpeed = segment.Link.PostSpeedMPH;
                            segment.Link.Results.FreeFlowSpeedMPH  = segment.Link.Results.BaseFreeFlowSpeed + 5;
                        }

                        segment.Link.AdjDDHV = 0;
                        for (int Movement = 0; Movement < 3; Movement++)
                        {
                            segment.Link.AdjDDHV += ODdata.SegOriginVol[Arterial.Segments.IndexOf(segment) - 1, (int)segDirection, 0, Movement]; // CNB: May not necessarily be AdjDDHV. Could be Midsegment Volume.
                        }

                        segment.Link.Results.RunningTimeCalcParms = SegmentCalcs.GetRunningTimeParms(Project.AnalMode, Arterial.Area, segment.Link.Results.FreeFlowSpeedMPH, segment.Link.AdjDDHV, segment.Link.NumLanes, segment.LengthFt, segment.Link.OnStreetParkingExists, segment.Link.ParkingActivity, segment.Link.AccessPoints.Count, segment.Link.AccessPoints.Count);
                        //segment.Link.Results.RunningTimeCalcParms = SegmentCalcs.GetRunningTimeParms(Project.AnalMode, Arterial.Area, segment.Link.Results.FreeFlowSpeedMPH, Arterial.TestSerVol, segment.Link.NumLanes, segment.Link.LengthFt, segment.Link.OnStreetParkingExists, segment.Link.ParkingActivity, segment.Link.AccessPoints.Count, segment.Link.AccessPoints.Count);
                        SegmentData upstreamSegment = Arterial.Segments[Arterial.Segments.IndexOf(segment) - 1];
                        if (Project.AnalMode == AnalysisMode.Operations)
                        {
                            segment.Link.Results.DischargeFlowProfile = CalcsFlowProfiles.ComputeDischargeFlowProfile(upstreamSegment, inputMovementsArray);
                            for (int accessPtIndex = 0; accessPtIndex < upstreamSegment.Link.AccessPoints.Count; accessPtIndex++)
                            {
                                for (int TimeIndex = 0; TimeIndex < upstreamSegment.Intersection.Signal.CycleLengthSec; TimeIndex++)
                                {
                                    segment.Link.Results.DischargeFlowProfile[3, TimeIndex] = ODdata.SegOriginVol[Arterial.Segments.IndexOf(upstreamSegment), (int)segDirection, accessPtIndex + 1, 3] / 3600;
                                }
                                segment.Link.Results.RunTimeSec           = SegmentCalcs.RunningTime(segment.Link.Results.RunningTimeCalcParms, segment.Link.Results.FreeFlowSpeedMPH, segment.LengthFt * upstreamSegment.Link.AccessPoints[accessPtIndex].Location, Project.AnalMode);
                                segment.Link.Results.ProjectedFlowProfile = CalcsFlowProfiles.ComputeProjectedProfile(segment, segment.Link.Results.RunTimeSec);
                            }
                            for (int TimeIndex = 0; TimeIndex < upstreamSegment.Intersection.Signal.CycleLengthSec; TimeIndex++)
                            {
                                segment.Link.Results.DischargeFlowProfile[3, TimeIndex] = ODdata.SegOriginVol[Arterial.Segments.IndexOf(upstreamSegment), (int)segDirection, 0, 3] / 3600;
                            }
                        }
                        //Eq. 18-7
                        segment.Link.Results.RunTimeSec             = SegmentCalcs.RunningTime(segment.Link.Results.RunningTimeCalcParms, segment.Link.Results.FreeFlowSpeedMPH, segment.LengthFt, Project.AnalMode);
                        segment.Link.Results.RunSpeedMPH            = (segment.LengthFt / segment.Link.Results.RunTimeSec) * (3600 / (float)5280);           //segment.Intersection.Width
                        segment.Link.Results.BaseFreeFlowTravelTime = SegmentCalcs.BaseFFTravTime(segment.LengthFt, segment.Link.Results.BaseFreeFlowSpeed); //segment.Intersection.Width
                        segment.Link.Results.FreeFlowTravelTime     = SegmentCalcs.FFTravTime(segment.LengthFt, segment.Link.Results.FreeFlowSpeedMPH);
                        segment.Link.Results.ProjectedFlowProfile   = CalcsFlowProfiles.ComputeProjectedProfile(segment, segment.Link.Results.RunTimeSec);
                    }

                    /* Necessary Inputs to run Signalized Intersection Module:
                     * ComputeQAPolygon*
                     * All Phases
                     * Cycle Length
                     *
                     * VolumeComputations*
                     * All Phases
                     *
                     * MaximumAllowableHeadway*
                     * All Phases
                     * Posted Speed
                     *
                     * ComputeEquivalentMaxGreen*
                     * All Phases
                     * Reference Phase ID
                     * Cycle Length
                     * Offset
                     * Cycle Force Mode
                     *
                     * ComputeAveragePhaseDuration*
                     * All Phases
                     * Detector Length (specifically, the one for a movement, so possibly lane group detector length)
                     * Cycle Length
                     */

                    foreach (ApproachData approach in segment.Intersection.Approaches)
                    {
                        foreach (LaneGroupData laneGroup in approach.LaneGroups)
                        {
                            if (laneGroup.Type == LaneMovementsAllowed.LeftOnly || laneGroup.Type == LaneMovementsAllowed.ThruAndLeftTurnBay)
                            {
                                approach.LeftTurnBayExists = true;
                            }
                            else if (laneGroup.Type == LaneMovementsAllowed.RightOnly || laneGroup.Type == LaneMovementsAllowed.ThruAndRightTurnBay)
                            {
                                approach.RightTurnBayExists = true;
                            }
                        }

                        approach.Results = new ResultsIntersectionApproachData(segment.Intersection.Signal.CycleLengthSec);
                        approach.Results.ControlDelay = 0;
                        approach.DemandVolume         = 0;
                        if (Arterial.Segments.IndexOf(segment) > 0)
                        {
                            approach.Results.ArrivalFlowProfile = CalcsFlowProfiles.ComputeArrivalFlowProfile(segment, Arterial.Segments.IndexOf(segment) - 1, approach, 0, segDirection, ODdata);
                        }

                        foreach (LaneGroupData laneGroup in approach.LaneGroups)
                        {
                            laneGroup.AnalysisResults = new ResultsIntersectionLaneGroupData();

                            if (segDirection == SegmentDirection.EBNB || Project.AnalMode == AnalysisMode.Planning)
                            {
                                if (laneGroup.DischargeVolume > 0)
                                {
                                    laneGroup.PortionOnGreen = Math.Min(Math.Min(laneGroup.PlatoonRatio, 2) * laneGroup.SignalPhase.GreenEffectiveSec / segment.Intersection.Signal.CycleLengthSec, 1); // includes green
                                }
                                else
                                {
                                    laneGroup.PortionOnGreen = 0;
                                }
                            }

                            if (Project.AnalMode == AnalysisMode.Operations && (laneGroup.NemaMvmtID == outputMovementsArray[0] || laneGroup.NemaMvmtID == outputMovementsArray[1] || laneGroup.NemaMvmtID == outputMovementsArray[2]))
                            {
                                if (Arterial.Segments.IndexOf(segment) > 0)
                                {
                                    if (laneGroup.Type == LaneMovementsAllowed.LeftOnly)
                                    {
                                        laneGroup.PortionOnGreen = CalcsFlowProfiles.ComputePortionOnGreen(segment, approach, laneGroup, 0, segDirection);
                                    }
                                    else if (laneGroup.Type == LaneMovementsAllowed.RightOnly)
                                    {
                                        laneGroup.PortionOnGreen = CalcsFlowProfiles.ComputePortionOnGreen(segment, approach, laneGroup, 2, segDirection);
                                    }
                                    else if (laneGroup.Type == LaneMovementsAllowed.ThruRightShared)
                                    {
                                        laneGroup.PortionOnGreen             = CalcsFlowProfiles.ComputePortionOnGreen(segment, approach, laneGroup, 1, segDirection);
                                        laneGroup.PortionOnGreenOfSharedLane = CalcsFlowProfiles.ComputePortionOnGreen(segment, approach, laneGroup, 2, segDirection);
                                    }
                                    else if (laneGroup.Type == LaneMovementsAllowed.ThruLeftShared)
                                    {
                                        laneGroup.PortionOnGreen             = CalcsFlowProfiles.ComputePortionOnGreen(segment, approach, laneGroup, 1, segDirection);
                                        laneGroup.PortionOnGreenOfSharedLane = CalcsFlowProfiles.ComputePortionOnGreen(segment, approach, laneGroup, 0, segDirection);
                                    }
                                    else
                                    {
                                        laneGroup.PortionOnGreen = CalcsFlowProfiles.ComputePortionOnGreen(segment, approach, laneGroup, 1, segDirection);
                                    }
                                }
                            }

                            //TimerData TimerForLaneGroup = MovementData.GetTimerForMovement(segment, laneGroup.NemaMvmtID);
                            //laneGroup.Results.AdjThruVol = SignalCalcs.ThruVolume(Art.PHF, Segs[i].DDHV, Intersections[i + 1].PTXL);

                            if (Project.AnalMode == AnalysisMode.Operations)
                            {
                                laneGroup.AnalysisResults.SatFlowRate = SatFlowRateCalculations.HCM2016(Arterial.Area, laneGroup.NumLanes, 12, laneGroup.PctHeavyVehicles, laneGroup.Type, laneGroup.PctLeftTurns, laneGroup.PctRightTurns, approach.PctGrade, laneGroup.BaseSatFlow);
                            }
                            else if (Project.AnalMode == AnalysisMode.Planning)
                            {
                                laneGroup.AnalysisResults.SatFlowRate = SatFlowRateCalculations.Planning(Project.Mode, Arterial.Area, segment.Link.OutsideLaneWidth, 12, laneGroup.DemandVolumeVehPerHr, laneGroup.PctHeavyVehicles, laneGroup.NumLanes, segment.Link.MedType, segment.Link.PostSpeedMPH, approach.LeftTurnBayExists, approach.RightTurnBayExists, approach.PctLeftTurns, approach.PctRightTurns, segment.Intersection.Signal.CycleLengthSec, segment.Link.PctGrade, laneGroup.BaseSatFlow);
                            }

                            laneGroup.SignalPhase.gC = laneGroup.SignalPhase.GreenEffectiveSec / segment.Intersection.Signal.CycleLengthSec; //Equation 19-16

                            laneGroup.AnalysisResults.CapacityPerLane = SignalCalcs.Capacity(laneGroup.AnalysisResults.SatFlowRate.AdjustedValueVehHrLane, laneGroup.SignalPhase.gC, laneGroup.NumLanes);
                            laneGroup.AnalysisResults.vcRatio         = SignalCalcs.vcRatio(laneGroup.AnalysisFlowRate, laneGroup.AnalysisResults.CapacityPerLane);

                            if (Arterial.Segments.IndexOf(segment) > 0 && (laneGroup.NemaMvmtID == NemaMovementNumbers.EBThru || laneGroup.NemaMvmtID == NemaMovementNumbers.WBThru))
                            {
                                laneGroup.AnalysisResults.OverCap = SignalCalcs.OverCapacityCheck(laneGroup.AnalysisResults.vcRatio, laneGroup.PeakHourFactor);
                            }

                            if (laneGroup.AnalysisResults.OverCap)
                            {
                                Arterial.OverCapacity = true;
                            }

                            if (Arterial.Segments.IndexOf(segment) == 0)
                            {
                                PrevVC = laneGroup.AnalysisResults.vcRatio;
                            }
                            else
                            {
                                PrevVC = Arterial.Segments[Arterial.Segments.IndexOf(segment) - 1].Intersection.Approaches[segment.Intersection.Approaches.IndexOf(approach)].LaneGroups[approach.LaneGroups.IndexOf(laneGroup)].AnalysisResults.vcRatio;
                            }

                            if (laneGroup.NemaMvmtID == NemaMovementNumbers.EBThru && Arterial.TestSerVol == 730)
                            {
                            }
                            laneGroup.AnalysisResults.SignalControlParms = SignalCalcs.SigDelay(segment.Intersection.Signal.ControlType, segment.Intersection.Signal.CycleLengthSec, laneGroup.SignalPhase.gC, laneGroup.ArvType, laneGroup.AnalysisFlowRate, laneGroup.AnalysisResults.SatFlowRate.AdjustedValueVehHrLane, laneGroup.NumLanes, laneGroup.AnalysisResults.CapacityPerLane, laneGroup.AnalysisResults.vcRatio, PrevVC, laneGroup.PortionOnGreen, laneGroup.NemaMvmtID);
                            laneGroup.AnalysisResults.LOS = SignalCalcs.LOSintersection(laneGroup.AnalysisResults.SignalControlParms.AvgOverallDelay, segment.Thresholds.Delay);     //determine intersection LOS, as a function of signal delay

                            if (approach.Dir == Arterial.AnalysisTravelDir && (laneGroup.Type == LaneMovementsAllowed.ThruOnly || laneGroup.Type == LaneMovementsAllowed.ThruRightShared))
                            {
                                AnalysisLaneGroupControlDelay = laneGroup.AnalysisResults.SignalControlParms.AvgOverallDelay;
                            }

                            approach.Results.ControlDelay += (laneGroup.AnalysisFlowRate * laneGroup.AnalysisResults.SignalControlParms.AvgOverallDelay) / approach.DemandVolume;
                            approach.DemandVolume         += laneGroup.AnalysisFlowRate;
                            //PrevVC = laneGroup.AnalysisResults.vcRatio;
                        }

                        segment.Intersection.DemandVolumeVehPerHr += approach.DemandVolume;
                        segment.Intersection.Results.ControlDelay += ((approach.Results.ControlDelay * approach.DemandVolume) / segment.Intersection.DemandVolumeVehPerHr);
                    }

                    //if (segment.Intersection.Signal.ControlType != SigControlType.Pretimed)
                    //{
                    //segment.Intersection.Signal.Phases = SignalCalcs.ComputeQAPolygon(segment.Intersection.Signal.Phases, segment.Intersection.Signal.CycleLengthSec);
                    //segment.Intersection.Signal.Phases = SignalCalcs.VolumeComputations(segment.Intersection.Signal.Phases);
                    //segment.Intersection.Signal.Phases = SignalCalcs.MaximumAllowableHeadway(segment.Intersection.Signal.Phases, segment.Link.PostSpeedMPH);
                    //segment.Intersection.Signal.Phases = SignalCalcs.ComputeEquivalentMaxGreen(segment.Intersection);
                    //segment.Intersection.Signal.Phases = SignalCalcs.ComputeAveragePhaseDuration(segment.Intersection.Signal.Phases, segment.Intersection.Signal.CycleLengthSec);
                    //}

                    foreach (AccessPointData accessPoint in segment.Link.AccessPoints)
                    {
                        if (segment.Id > 0) //SSW: added 4/1/21, review
                        {
                            accessPoint.ArrivalFlowRate    = CalcsFlowProfiles.ComputeConflictFlowRate(segment, accessPoint, segment.Intersection.Approaches[(int)Arterial.AnalysisTravelDir], outputMovementsArray, segDirection);
                            accessPoint.BlockTime          = CalcsFlowProfiles.ComputeBlockTime(segment, accessPoint);
                            accessPoint.PortionTimeBlocked = CalcsFlowProfiles.ComputePortionTimeBlocked(segment, accessPoint);
                        }
                    }

                    segment.Results.TravelTime   = segment.Link.Results.RunTimeSec + AnalysisLaneGroupControlDelay;
                    segment.Results.AverageSpeed = SegmentCalcs.SegAvgSpeed(segment.LengthFt, segment.Results.TravelTime);

                    if (segment.Results.AverageSpeed < Arterial.Results.CritSpeed)
                    {
                        Arterial.Results.CritSpeed = segment.Results.AverageSpeed;    //save lowest segment speed to use for arterial speed if an intersection v/c is greater than 1/PHF
                    }
                    segment.Thresholds       = new ThresholdData(Arterial.Area, segment.Link.PostSpeedMPH);
                    segment.Link.Results.LOS = SegmentCalcs.LOSsegmentAuto(segment.Results.AverageSpeed, segment.Thresholds.Speed);
                    //Art.Results.BaseFreeFlowTravelTime += segment.Link.Results.BaseFreeFlowTravelTime;
                    //Art.Results.FreeFlowTravelTime += segment.Link.Results.FreeFlowTravelTime;
                    if (Arterial.Segments.IndexOf(segment) > 0 && segDirection == SegmentDirection.EBNB)
                    {
                        Arterial.Results.TravelTime += segment.Results.TravelTime;
                        //Art.Results.TotalgC += Intersections[i + 1].gCthru;
                        TotalLaneFeet += segment.Link.NumLanes * segment.LengthFt;    // + Intersections[IntIndex].Width);
                    }
                }

                if (segDirection == SegmentDirection.WBSB)
                {
                    ReverseArterial(ref Arterial);
                }

                if (segDirection == SegmentDirection.EBNB)
                {
                    //Art.AvgSegLength = Art.LengthMiles * 5280 / Art.TotalSegs;
                    //Art.WtdgC = WeightedgC(Art.TotalSegs, ArtTotgC, CritgC);     //Calculate weighted g/C for arterial
                    //Art.FFSdelay = FFSDelay(ArtTravTime, ArtFFTravTime);            //Calculate Free-Flow speed delay
                    //Art.ThreshDelay = ThresholdDelay(Art.Area, ArtTravTime, ArtLengthMiles);    //Calculate Threshold delay
                    Arterial.Results.AverageSpeed = 3600 * Arterial.LengthMiles / Arterial.Results.TravelTime;
                    //Art.Results.BaseFreeFlowSpeed = 3600 * Art.LengthMiles / Art.Results.BaseFreeFlowTravelTime;
                    //Art.Results.SpeedRatio = Art.Results.AverageSpeed / Art.Results.BaseFreeFlowSpeed;
                    Arterial.Results.LOS = SegmentCalcs.LOSsegmentAuto(Arterial.Results.AverageSpeed, Arterial.Thresholds.Speed);
                    //Art.Results.AvgLanes = TotalLaneFeet / (Art.Results.LengthMiles * 5280);  //length weighted average number of lanes for the arterial; used in the bike & ped service vol calcs
                    if (Arterial.OverCapacity == true)
                    {
                        Arterial.Results.AverageSpeed = Arterial.Results.CritSpeed;
                        Arterial.Results.LOS          = "F";
                    }
                }
            }
        }
Esempio n. 11
0
        public static void ChangeArterialVolume(ref ArterialData Arterial, float analysisDirectionDemandVol = 800)
        {
            float minorStreetVolumeRatio       = 0.75f;
            float midSegVolumeRatio            = 0.5f;
            float midSegAnalysisDirVolumeRatio = 0.1276f;
            float leftTurningPctInt            = 0.1f;     // 0.125f
            float rightTurningPctInt           = 0.1f;     // 0.125f
            float leftTurningPctAP             = 1f / 20f; // 0.125f
            float rightTurningPctAP            = 1f / 20f; // 0.125f

            float[] demandVolumesLeft     = { analysisDirectionDemandVol *leftTurningPctInt, analysisDirectionDemandVol *leftTurningPctInt, minorStreetVolumeRatio *analysisDirectionDemandVol *leftTurningPctInt, minorStreetVolumeRatio *analysisDirectionDemandVol *leftTurningPctInt };
            float[] demandVolumesThru     = { analysisDirectionDemandVol *(1 - (leftTurningPctInt + rightTurningPctInt)), analysisDirectionDemandVol *(1 - (leftTurningPctInt + rightTurningPctInt)), minorStreetVolumeRatio *analysisDirectionDemandVol *(1 - (leftTurningPctInt + rightTurningPctInt)), minorStreetVolumeRatio *analysisDirectionDemandVol *(1 - (leftTurningPctInt + rightTurningPctInt)) };
            float[] demandVolumesRight    = { analysisDirectionDemandVol *rightTurningPctInt, analysisDirectionDemandVol *rightTurningPctInt, minorStreetVolumeRatio *analysisDirectionDemandVol *rightTurningPctInt, minorStreetVolumeRatio *analysisDirectionDemandVol *rightTurningPctInt };
            float   EBApproachAccessPoint = demandVolumesThru[0] + demandVolumesRight[2] + demandVolumesLeft[3];
            float   WBApproachAccessPoint = demandVolumesThru[1] + demandVolumesRight[3] + demandVolumesLeft[2];                                                                                      // The + 20 needs to be investigated

            float[] demandVolumesAP1EB = { leftTurningPctAP *EBApproachAccessPoint, (1 - (leftTurningPctAP + rightTurningPctAP)) * EBApproachAccessPoint, rightTurningPctAP *EBApproachAccessPoint }; // EBT + NBR + SBL EWNS
            float[] demandVolumesAP1WB = { leftTurningPctAP *WBApproachAccessPoint, (1 - (leftTurningPctAP + rightTurningPctAP)) * WBApproachAccessPoint, rightTurningPctAP *WBApproachAccessPoint }; // WBT + NBL + SBR
            float[] demandVolumesAP1NB = { midSegVolumeRatio *midSegAnalysisDirVolumeRatio *WBApproachAccessPoint, 0, (1 - midSegVolumeRatio) * midSegAnalysisDirVolumeRatio * EBApproachAccessPoint };
            float[] demandVolumesAP1SB = { (1 - midSegVolumeRatio) * midSegAnalysisDirVolumeRatio * EBApproachAccessPoint, 0, midSegVolumeRatio *midSegAnalysisDirVolumeRatio *WBApproachAccessPoint };

            EBApproachAccessPoint = demandVolumesAP1EB[1] + demandVolumesAP1NB[2] + demandVolumesAP1SB[0];                                                                                            // The + 20 needs to be investigated
            WBApproachAccessPoint = demandVolumesThru[1] + demandVolumesRight[3] + demandVolumesLeft[2];
            float[] demandVolumesAP2EB = { leftTurningPctAP *EBApproachAccessPoint, (1 - (leftTurningPctAP + rightTurningPctAP)) * EBApproachAccessPoint, rightTurningPctAP *EBApproachAccessPoint }; // EBT + NBR + SBL EWNS
            float[] demandVolumesAP2WB = { leftTurningPctAP *WBApproachAccessPoint, (1 - (leftTurningPctAP + rightTurningPctAP)) * WBApproachAccessPoint, rightTurningPctAP *WBApproachAccessPoint }; // WBT + NBL + SBR
            float[] demandVolumesAP2NB = { midSegVolumeRatio *midSegAnalysisDirVolumeRatio *WBApproachAccessPoint, 0, (1 - midSegVolumeRatio) * midSegAnalysisDirVolumeRatio * EBApproachAccessPoint };
            float[] demandVolumesAP2SB = { (1 - midSegVolumeRatio) * midSegAnalysisDirVolumeRatio * EBApproachAccessPoint, 0, midSegVolumeRatio *midSegAnalysisDirVolumeRatio *WBApproachAccessPoint };


            float[] demandVolumesAP1 = { demandVolumesAP1EB[0], demandVolumesAP1EB[1], demandVolumesAP1EB[2],
                                         demandVolumesAP1WB[0], demandVolumesAP1WB[1], demandVolumesAP1WB[2],
                                         demandVolumesAP1NB[0], demandVolumesAP1NB[1], demandVolumesAP1NB[2],
                                         demandVolumesAP1SB[0], demandVolumesAP1SB[1], demandVolumesAP1SB[2], };

            float[] demandVolumesAP2 = { demandVolumesAP2EB[0], demandVolumesAP2EB[1], demandVolumesAP2EB[2],
                                         demandVolumesAP2WB[0], demandVolumesAP2WB[1], demandVolumesAP2WB[2],
                                         demandVolumesAP2NB[0], demandVolumesAP2NB[1], demandVolumesAP2NB[2],
                                         demandVolumesAP2SB[0], demandVolumesAP2SB[1], demandVolumesAP2SB[2], };

            foreach (SegmentData Segment in Arterial.Segments)
            {
                Segment.Link.AccessPoints[0].Volume = demandVolumesAP1;
                Segment.Link.AccessPoints[1].Volume = demandVolumesAP2;
                foreach (ApproachData Approach in Segment.Intersection.Approaches)
                {
                    int   travelDirectionIndex = (int)Approach.Dir;
                    float totalDemand          = demandVolumesLeft[travelDirectionIndex] + demandVolumesThru[travelDirectionIndex] + demandVolumesRight[travelDirectionIndex];
                    Approach.DemandVolume  = totalDemand;
                    Approach.PctLeftTurns  = (demandVolumesLeft[travelDirectionIndex] / totalDemand) * 100;
                    Approach.PctRightTurns = (demandVolumesRight[travelDirectionIndex] / totalDemand) * 100;

                    foreach (LaneGroupData LaneGroup in Approach.LaneGroups)
                    {
                        if (LaneGroup.Type == LaneMovementsAllowed.LeftOnly)
                        {
                            LaneGroup.DischargeVolume      = demandVolumesLeft[travelDirectionIndex];
                            LaneGroup.DemandVolumeVehPerHr = demandVolumesLeft[travelDirectionIndex];
                        }
                        if (LaneGroup.Type == LaneMovementsAllowed.ThruRightShared)
                        {
                            LaneGroup.DischargeVolume      = demandVolumesThru[travelDirectionIndex] + demandVolumesRight[travelDirectionIndex];
                            LaneGroup.DemandVolumeVehPerHr = demandVolumesThru[travelDirectionIndex] + demandVolumesRight[travelDirectionIndex];
                            LaneGroup.PctRightTurns        = demandVolumesRight[travelDirectionIndex] / (demandVolumesThru[travelDirectionIndex] + demandVolumesRight[travelDirectionIndex]) * 100;
                        }
                        LaneGroup.AnalysisFlowRate = LaneGroup.CalcAnalysisFlowRate(LaneGroup.DemandVolumeVehPerHr, LaneGroup.PeakHourFactor);
                    }
                }
            }
        }
Esempio n. 12
0
        public static ArterialData NewArterial(AnalysisMode ProjectAnalMode, float analysisDirectionDemandVol = 800, int numLanes = 2)
        {
            // Timers

            /*TimerData Timer1 = new TimerData(1, NemaMovementNumbers.WBLeft, 15.9f, 3, 35.27f, 51.16f, 3.13f, 30.73f, 12.646f, 0.311f, 0.995f, 0);
             * TimerData Timer2 = new TimerData(5, NemaMovementNumbers.EBLeft, 16.1f, 3, 35.27f, 51.37f, 3.13f, 30.73f, 12.829f, 0.322f, 0.996f, 0);
             * TimerData Timer3 = new TimerData(2, NemaMovementNumbers.EBThru, 52.84f, 4, 51.16f, 4f, 0, 0, 0, 0, 0, 0);
             * TimerData Timer4 = new TimerData(6, NemaMovementNumbers.WBThru, 52.63f, 4, 51.37f, 4f, 0, 0, 0, 0, 0, 0);
             * TimerData Timer5 = new TimerData(3, NemaMovementNumbers.NBLeft, 9.13f, 3, 4, 13.13f, 3.13f, 17, 6.442f, 0.099f, 0.938f, 0);
             * TimerData Timer6 = new TimerData(7, NemaMovementNumbers.SBLeft, 9.13f, 3, 4, 13.13f, 3.13f, 17, 6.442f, 0.099f, 0.938f, 0);
             * TimerData Timer7 = new TimerData(4, NemaMovementNumbers.SBThru, 22.13f, 4, 13.14f, 35.27f, 3.06f, 31.87f, 16.165f, 1.968f, 1, 0.016f);
             * TimerData Timer8 = new TimerData(8, NemaMovementNumbers.NBThru, 22.13f, 4, 13.14f, 35.27f, 3.06f, 31.87f, 16.165f, 1.968f, 1, 0.016f);*/

            List <SegmentData> Segments = new List <SegmentData>();

            // Intersection 1 / First Ave. //// "Segment-less" Intersection
            TimerData        TimerWBL = new TimerData(11.50f, 4.00f, 39.75f, 51.25f, 3.13f, 35.25f, 7.886f, 0.120f, 0.936f, 0.000f);
            TimerData        TimerEBT = new TimerData(76.75f, 4.00f, 51.25f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerData        TimerNBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerData        TimerSBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            TimerData        TimerEBL = new TimerData(11.45f, 4.00f, 39.75f, 51.20f, 3.13f, 35.25f, 7.832f, 0.120f, 0.936f, 0.000f);
            TimerData        TimerWBT = new TimerData(76.80f, 4.00f, 51.20f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerData        TimerSBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerData        TimerNBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            List <TimerData> Timers   = new List <TimerData> {
                TimerWBL, TimerEBL, TimerEBT, TimerWBT, TimerNBL, TimerSBL, TimerSBT, TimerNBT
            };

            IntersectionData newIntersection;
            LinkData         newLink;
            int upstreamIntersectionWidth = 0;

            newIntersection = CreateIntersection(Timers, numLanes, ProjectAnalMode, 60);
            newLink         = new LinkData(0, numLanes, 35, 0.94f, MedianType.None);
            Segments.Add(new SegmentData(0, newLink, newIntersection, AreaType.LargeUrbanized, newLink.PostSpeedMPH + 5, upstreamIntersectionWidth));
            upstreamIntersectionWidth = newIntersection.CrossStreetWidth;
            Segments[0].Link.AccessPoints.Add(CreateAPIntersection(1f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));
            Segments[0].Link.AccessPoints.Add(CreateAPIntersection(2f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));

            // Intersection 2 / Second Ave.
            TimerWBL = new TimerData(11.50f, 4.00f, 39.75f, 51.25f, 3.13f, 35.25f, 7.886f, 0.120f, 0.936f, 0.000f);
            TimerEBT = new TimerData(76.75f, 4.00f, 51.25f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerNBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerSBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            TimerEBL = new TimerData(11.49f, 4.00f, 39.75f, 51.24f, 3.13f, 35.25f, 7.877f, 0.120f, 0.936f, 0.000f);
            TimerWBT = new TimerData(76.76f, 4.00f, 51.24f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerSBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerNBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            Timers   = new List <TimerData> {
                TimerWBL, TimerEBL, TimerEBT, TimerWBT, TimerNBL, TimerSBL, TimerSBT, TimerNBT
            };

            newIntersection = CreateIntersection(Timers, numLanes, ProjectAnalMode, 60);
            newLink         = new LinkData(1320 - upstreamIntersectionWidth, numLanes, 35, 0.94f, MedianType.None);
            Segments.Add(new SegmentData(1, newLink, newIntersection, AreaType.LargeUrbanized, newLink.PostSpeedMPH + 5, upstreamIntersectionWidth));
            upstreamIntersectionWidth = newIntersection.CrossStreetWidth;
            Segments[1].Link.AccessPoints.Add(CreateAPIntersection(1f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));
            Segments[1].Link.AccessPoints.Add(CreateAPIntersection(2f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));

            // Intersection 3 / Third Ave.
            TimerWBL = new TimerData(11.50f, 4.00f, 39.75f, 51.25f, 3.13f, 35.25f, 7.885f, 0.120f, 0.936f, 0.000f);
            TimerEBT = new TimerData(76.75f, 4.00f, 51.25f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerNBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerSBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            TimerEBL = new TimerData(11.48f, 4.00f, 39.75f, 51.23f, 3.13f, 35.25f, 7.872f, 0.119f, 0.936f, 0.000f);
            TimerWBT = new TimerData(76.77f, 4.00f, 51.23f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerSBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerNBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            Timers   = new List <TimerData> {
                TimerWBL, TimerEBL, TimerEBT, TimerWBT, TimerNBL, TimerSBL, TimerSBT, TimerNBT
            };

            newIntersection = CreateIntersection(Timers, numLanes, ProjectAnalMode, 60);
            newLink         = new LinkData(1320 - upstreamIntersectionWidth, numLanes, 35, 0.94f, MedianType.None);
            Segments.Add(new SegmentData(2, newLink, newIntersection, AreaType.LargeUrbanized, newLink.PostSpeedMPH + 5, upstreamIntersectionWidth));
            upstreamIntersectionWidth = newIntersection.CrossStreetWidth;
            Segments[2].Link.AccessPoints.Add(CreateAPIntersection(1f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));
            Segments[2].Link.AccessPoints.Add(CreateAPIntersection(2f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));

            // Intersection 4 / Fourth Ave.
            TimerWBL = new TimerData(11.50f, 4.00f, 39.75f, 51.25f, 3.19f, 35.25f, 7.884f, 0.125f, 0.936f, 0.000f);
            TimerEBT = new TimerData(76.75f, 4.00f, 51.25f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerNBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerSBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            TimerEBL = new TimerData(11.48f, 4.00f, 39.75f, 51.23f, 3.13f, 35.25f, 7.868f, 0.119f, 0.936f, 0.000f);
            TimerWBT = new TimerData(76.77f, 4.00f, 51.23f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerSBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerNBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            Timers   = new List <TimerData> {
                TimerWBL, TimerEBL, TimerEBT, TimerWBT, TimerNBL, TimerSBL, TimerSBT, TimerNBT
            };

            newIntersection = CreateIntersection(Timers, numLanes, ProjectAnalMode, 60);
            newLink         = new LinkData(1320 - upstreamIntersectionWidth, numLanes, 35, 0.94f, MedianType.None);
            Segments.Add(new SegmentData(3, newLink, newIntersection, AreaType.LargeUrbanized, newLink.PostSpeedMPH + 5, upstreamIntersectionWidth));
            upstreamIntersectionWidth = newIntersection.CrossStreetWidth;
            Segments[3].Link.AccessPoints.Add(CreateAPIntersection(1f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));
            Segments[3].Link.AccessPoints.Add(CreateAPIntersection(2f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));

            // Intersection 5 / Fifth Ave.
            TimerWBL = new TimerData(11.50f, 4.00f, 39.75f, 51.25f, 3.19f, 35.25f, 7.883f, 0.125f, 0.936f, 0.000f);
            TimerEBT = new TimerData(76.75f, 4.00f, 51.25f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerNBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerSBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            TimerEBL = new TimerData(11.48f, 4.00f, 39.75f, 51.23f, 3.19f, 35.25f, 7.865f, 0.125f, 0.936f, 0.000f);
            TimerWBT = new TimerData(76.77f, 4.00f, 51.23f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerSBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerNBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            Timers   = new List <TimerData> {
                TimerWBL, TimerEBL, TimerEBT, TimerWBT, TimerNBL, TimerSBL, TimerSBT, TimerNBT
            };

            newIntersection = CreateIntersection(Timers, numLanes, ProjectAnalMode, 60);
            newLink         = new LinkData(660 - upstreamIntersectionWidth, numLanes, 30, 0.88f, MedianType.None);
            Segments.Add(new SegmentData(4, newLink, newIntersection, AreaType.LargeUrbanized, newLink.PostSpeedMPH + 5, upstreamIntersectionWidth));
            upstreamIntersectionWidth = newIntersection.CrossStreetWidth;
            Segments[4].Link.AccessPoints.Add(CreateAPIntersection(1f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));
            Segments[4].Link.AccessPoints.Add(CreateAPIntersection(2f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));

            // Intersection 6 / Sixth Ave.
            TimerWBL = new TimerData(11.45f, 4.00f, 39.75f, 51.20f, 3.19f, 35.25f, 7.832f, 0.125f, 0.936f, 0.000f);
            TimerEBT = new TimerData(76.80f, 4.00f, 51.20f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerNBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerSBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            TimerEBL = new TimerData(11.48f, 4.00f, 39.75f, 51.23f, 3.19f, 35.25f, 7.864f, 0.125f, 0.936f, 0.000f);
            TimerWBT = new TimerData(76.77f, 4.00f, 51.23f, 4.00f, 0.00f, 0.00f, 0.000f, 0.000f, 0.000f, 0.000f);
            TimerSBL = new TimerData(9.59f, 4.00f, 4.00f, 13.59f, 3.13f, 8.00f, 6.389f, 0.009f, 0.873f, 1.000f);
            TimerNBT = new TimerData(26.16f, 4.00f, 13.59f, 39.75f, 3.06f, 37.41f, 20.199f, 1.963f, 1.000f, 0.009f);
            Timers   = new List <TimerData> {
                TimerWBL, TimerEBL, TimerEBT, TimerWBT, TimerNBL, TimerSBL, TimerSBT, TimerNBT
            };

            newIntersection = CreateIntersection(Timers, numLanes, ProjectAnalMode, 60);
            newLink         = new LinkData(660 - upstreamIntersectionWidth, numLanes, 30, 0.88f, MedianType.None);
            Segments.Add(new SegmentData(5, newLink, newIntersection, AreaType.LargeUrbanized, newLink.PostSpeedMPH + 5, upstreamIntersectionWidth));
            Segments[5].Link.AccessPoints.Add(CreateAPIntersection(1f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));
            Segments[5].Link.AccessPoints.Add(CreateAPIntersection(2f / 3f, Segments[0].Intersection.Signal.CycleLengthSec));

            ArterialData newArterial = new ArterialData(AreaType.LargeUrbanized, ArterialClass.ClassI, TravelDirection.Eastbound, Segments);

            ChangeArterialVolume(ref newArterial, analysisDirectionDemandVol);

            // Calcs Arterial code
            foreach (SegmentData segment in newArterial.Segments)
            {
                newArterial.LengthMiles += segment.Link.LengthFt / 5280;
                foreach (ApproachData approach in segment.Intersection.Approaches)
                {
                    foreach (LaneGroupData laneGroup in approach.LaneGroups)
                    {
                        laneGroup.SignalPhase.GreenEffectiveSec = Math.Max(laneGroup.SignalPhase.Timer.Duration - laneGroup.SignalPhase.Timer.IntergreenTimeSec - laneGroup.SignalPhase.StartUpLostTimeSec + laneGroup.SignalPhase.EndUseSec, 0);
                        laneGroup.PctHeavyVehicles = 0; // 3%
                    }
                }
            }
            //newArterial.ThreshDelay = newArterial.GetLOSBoundaries_Delay(newArterial.Area);
            //newArterial.ThreshSpeed = newArterial.GetLOSBoundaries_Speed(artClass: 2);
            newArterial.AnalysisTravelDir = TravelDirection.Eastbound;

            return(newArterial);
        }
        public static ArterialData NewArterial(ServiceVolumeTableFDOT arterialInputs, AnalysisMode ProjectAnalMode, float analysisDirectionDemandVol = 800, int numLanes = 2)
        {
            arterialInputs.Signal.EffGreen     = arterialInputs.Signal.CalcEffectiveGreen(arterialInputs.Signal.EffGreenToCycleLengthRatio, arterialInputs.Signal.CycleLengthSec);
            arterialInputs.Signal.EffGreenLeft = arterialInputs.Signal.CalcEffectiveGreen(0.1f, arterialInputs.Signal.CycleLengthSec);
            List <SegmentData> Segments        = new List <SegmentData>();
            IntersectionData   newIntersection = CreateIntersection(numLanes, arterialInputs.Signal.CycleLengthSec, arterialInputs.SerVolAreaType, ProjectAnalMode);

            newIntersection.Signal.ControlType = arterialInputs.Signal.SigType;
            LinkData newLink;
            float    segmentLength;

            for (int intIndex = 0; intIndex < arterialInputs.Roadway.NumIntersections; intIndex++)
            {
                if (intIndex == 0)
                {
                    segmentLength = 0;
                }
                else
                {
                    segmentLength = arterialInputs.Roadway.ArterialLenghtFt / (arterialInputs.Roadway.NumIntersections - 1);
                }

                newLink = new LinkData(segmentLength - newIntersection.CrossStreetWidth, numLanes, arterialInputs.Roadway.PostedSpeedMPH, arterialInputs.Roadway.PropCurbRightSide, arterialInputs.Roadway.Median);
                Segments.Add(new SegmentData(intIndex, newLink, newIntersection, arterialInputs.SerVolAreaType, arterialInputs.Roadway.PostedSpeedMPH, newIntersection.CrossStreetWidth));
            }

            ArterialData newArterial = new ArterialData(arterialInputs, Segments);

            ChangeArterialVolume(ref newArterial, analysisDirectionDemandVol);

            // Calcs Arterial code
            foreach (SegmentData segment in newArterial.Segments)
            {
                foreach (ApproachData approach in segment.Intersection.Approaches)
                {
                    approach.PctLeftTurns  = arterialInputs.Traffic.PctLeftTurns;
                    approach.PctRightTurns = arterialInputs.Traffic.PctRightTurns;
                    foreach (LaneGroupData laneGroup in approach.LaneGroups)
                    {
                        if (laneGroup.Type == LaneMovementsAllowed.LeftOnly)
                        {
                            laneGroup.SignalPhase.GreenEffectiveSec = arterialInputs.Signal.EffGreenLeft;
                            laneGroup.TurnBayLeftLengthFeet         = arterialInputs.Roadway.TurnBayLeftLengthFeet;
                        }
                        else
                        {
                            laneGroup.SignalPhase.GreenEffectiveSec = arterialInputs.Signal.EffGreen;
                        }
                        laneGroup.BaseSatFlow      = arterialInputs.Traffic.BaseSatFlow;
                        laneGroup.PctHeavyVehicles = arterialInputs.Traffic.PctHeavyVeh;
                        laneGroup.ArvType          = arterialInputs.Signal.ArvType;
                        float[] PlatoonRatioValues = new float[] { 0.333f, 0.667f, 1.0f, 1.333f, 1.667f, 2.0f };
                        laneGroup.PlatoonRatio   = PlatoonRatioValues[laneGroup.ArvType - 1];
                        laneGroup.PeakHourFactor = arterialInputs.Traffic.PHF;
                    }
                }
            }
            newArterial.Thresholds.Delay  = newArterial.Thresholds.GetLOSBoundaries_Delay(newArterial.Area);
            newArterial.Thresholds.Speed  = newArterial.Thresholds.GetLOSBoundaries_Speed(arterialInputs.Roadway.PostedSpeedMPH);
            newArterial.AnalysisTravelDir = arterialInputs.Roadway.AnalysisTravelDir;

            return(newArterial);
        }