using System; using System.Collections.Generic; using System.Text; namespace OpenTraffic.Model.Route { public delegate bool LinkFunction(TrafficModelLink l); public class TrafficRoute { public float Length { get; private set; } public TrafficModelLink Source { get { return rc.Source; } } public TrafficModelLink Target { get { return rc.Target; } } public long Id { get { long id = SubId; id = id << 32; id += ConatinerId; return id; } } public int SubId { get { return subId; } } public int ConatinerId { get { return rc.Id; } } // xxx a bit bogus. I mean that the parallells links are not really found be contram public int RouteGeneratorId { get { return rc.RouteGeneratorId; } } private RouteContainer rc; private TrafficModelLink[] links; private float FreeFlowTravelTime; private ClassField Restrict; private int subId; public TrafficRoute(RouteContainer rc, TrafficModelLink[] links, int subId) { this.links = links; this.rc = rc; this.subId = subId; CalculateCachedValue(); } public void CalculateCachedValue() { Restrict = new ClassField(false); FreeFlowTravelTime = Source.CalculateFreeFlowTravelTime(); Length = Source.Length; foreach (TrafficModelLink l in links) { Length += l.Length; FreeFlowTravelTime += l.CalculateFreeFlowTravelTime(); if (l.Restrict != null) Restrict |= l.Restrict; } Length += Target.Length; FreeFlowTravelTime += Target.CalculateFreeFlowTravelTime(); if (Source.Restrict != null) Restrict |= Source.Restrict; if (Source.Restrict != null) Restrict |= Target.Restrict; } public bool Allowed(VehicleClass c) { if (Restrict != null) { return !Restrict.IsSet(c); } return true; } public TrafficModelLink GetLink(int pos) { if (pos == 0) return Source; if (pos <= links.Length) return links[pos - 1]; if (pos == links.Length + 1) return Target; return null; } public float GetObservedTotalTravelTime(float startTime, VehicleClass c, Result.ResultData res) { float time = startTime; time += Source.GetObservedTotalTravelTime(time, c, res); foreach (TrafficModelLink l in links) { time += l.GetObservedTotalTravelTime(time, c, res); } time += Target.GetObservedTotalTravelTime(time, c, res); return time - startTime; } public float GetObservedQueingTime(float startTime, VehicleClass c, Result.ResultData res) { if (res != null) { float time = startTime; float value = res.GetQueuingTime(time, Source); time += Source.GetObservedTotalTravelTime(time, c, res); foreach (TrafficModelLink l in links) { value += res.GetQueuingTime(time, l); time += l.GetObservedTotalTravelTime(time, c, res); } value += res.GetQueuingTime(time, Target); time += Target.GetObservedTotalTravelTime(time, c, res); return value; } return float.MaxValue; } public void Each(LinkFunction lf) { if (lf != null) { lf.Invoke(Source); foreach (TrafficModelLink l in links) { lf.Invoke(l); } lf.Invoke(Target); } } public override string ToString() { string str = "Route(" + Id + " ): " + Source.Source.Id + "->" + Target.Target.Id + ": "; str += Length + "m" + ": "; str += FreeFlowTravelTime + "s" + ":"; str += Source.Id; foreach (TrafficModelLink l in links) { str += " " + l.Id; } str += " " + Target.Id; return str; } public override int GetHashCode() { return rc.GetHashCode() + subId; } public override bool Equals(object obj) { if (obj != null) { TrafficRoute r = obj as TrafficRoute; if (r == null) { return false; } return r.rc == rc && r.SubId == subId; } return false; } public bool IsValid() { for (int i = 0; i < links.Length - 1; i++) { TrafficModelLink o = links[i]; TrafficModelLink d = links[i + 1]; bool ok = false; foreach (Turning t in o.Turnings) { if (t.Destination == d) { ok = true; } } if (ok == false) return false; } return true; } } }