ExtractedTimFrame BuildAlertFrame(string roadwayid, string text, DateTime startTime, int duration, double startMM, double endMM) { bool reversed = startMM > endMM; if (reversed) { double swap = startMM; startMM = endMM; endMM = swap; } ExtractedTimFrame results = new ExtractedTimFrame(text, startTime, duration); var dbAlertMileMarkers = srInfloDbContext.Configuration_RoadwayMileMarkers .Where(r => r.RoadwayId.Equals(roadwayid)); //Snap to closest milemarkers by widening the alert. try { startMM = dbAlertMileMarkers.Where(m => m.MMNumber <= startMM).OrderByDescending(m => m.MMNumber).First().MMNumber; } catch { } try { endMM = dbAlertMileMarkers.Where(m => m.MMNumber >= endMM).OrderBy(m => m.MMNumber).First().MMNumber; } catch { } dbAlertMileMarkers = dbAlertMileMarkers.Where(m => startMM <= m.MMNumber && m.MMNumber <= endMM); if (reversed) { dbAlertMileMarkers = dbAlertMileMarkers.OrderByDescending(m => m.MMNumber); } else { dbAlertMileMarkers = dbAlertMileMarkers.OrderBy(m => m.MMNumber); } var dbAlertMileMarkersList = dbAlertMileMarkers.ToList(); List <ExtractedNodeList> alertPaths = new List <ExtractedNodeList>(); while (dbAlertMileMarkersList.Count() > 1) { var mmarkers = dbAlertMileMarkersList.GetRange(0, Math.Min(MileMarkersPerValidRegion, dbAlertMileMarkersList.Count())); List <Extracted3DOffset> nodes = new List <Extracted3DOffset>(); if (reversed) { mmarkers.OrderByDescending(m => m.MMNumber).ToList().ForEach(m => nodes.Add(new Extracted3DOffset(m.Latitude2, m.Longitude2, m.MMNumber))); } else { mmarkers.OrderBy(m => m.MMNumber).ToList().ForEach(m => nodes.Add(new Extracted3DOffset(m.Latitude1, m.Longitude1, m.MMNumber))); } if (nodes.Count > 1) { ExtractedNodeList alertPath = new ExtractedNodeList(nodes.ToArray()); alertPaths.Add(alertPath); } dbAlertMileMarkersList.RemoveRange(0, mmarkers.Count() - 1); } results.setAlertPaths(alertPaths.ToArray()); return(results); }
// GET api/tim public HttpResponseMessage Get(string roadwayid, double mm) { Trace.TraceInformation("[TRACE] Entering TimController::Get(string roadwayid, double mm)..."); if (srInfloDbContext == null) { return(this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Error connecting to Inflo DB")); } else { srInfloDbContext.ChangeTracker.DetectChanges(); //TODO reduce alerts we care about. var qWarnRoadwayAlerts = srInfloDbContext.TMEOutput_QWARNMessage_CV.Where(a => a.RoadwayID.Equals(roadwayid)) /*.Where(a => System.Data.Entity.DbFunctions.AddSeconds(a.DateGenerated, a.ValidityDuration ?? 20) >= DateTime.UtcNow)*/; var qWarnIncrAlerts = qWarnRoadwayAlerts.Where(a => a.BOQMMLocation <= a.FOQMMLocation).Where(a => (mm + AlertSearchRadius) >= a.BOQMMLocation && (mm - AlertSearchRadius) <= a.FOQMMLocation).OrderByDescending(a => a.DateGenerated).Take(1); var qWarnDecrAlerts = qWarnRoadwayAlerts.Where(a => a.BOQMMLocation > a.FOQMMLocation).Where(a => (mm - AlertSearchRadius) <= a.BOQMMLocation && (mm + AlertSearchRadius) >= a.FOQMMLocation).OrderByDescending(a => a.DateGenerated).Take(1); var qWarnApplicableAlerts = qWarnIncrAlerts.Union(qWarnDecrAlerts).ToList(); var qWarnAheadIncrAlerts = qWarnRoadwayAlerts.Where(a => a.BOQMMLocation <= a.FOQMMLocation).Where(a => (mm + QWarnAheadDistance + AlertSearchRadius) >= a.BOQMMLocation && (mm - AlertSearchRadius) <= a.BOQMMLocation).OrderByDescending(a => a.DateGenerated).Take(1); var qWarnAheadDecrAlerts = qWarnRoadwayAlerts.Where(a => a.BOQMMLocation > a.FOQMMLocation).Where(a => (mm - QWarnAheadDistance - AlertSearchRadius) <= a.BOQMMLocation && (mm + AlertSearchRadius) >= a.BOQMMLocation).OrderByDescending(a => a.DateGenerated).Take(1); var qWarnAheadApplicableAlerts = qWarnAheadIncrAlerts.Union(qWarnAheadDecrAlerts).ToList(); var spdHarmRoadwayAlerts = srInfloDbContext.TMEOutput_SPDHARMMessage_CV.Where(a => a.RoadwayId.Equals(roadwayid)).Where(a => System.Data.Entity.DbFunctions.AddSeconds(a.DateGenerated, a.ValidityDuration ?? 20) >= DateTime.UtcNow); var spdHarmIncrAlerts = spdHarmRoadwayAlerts.Where(a => a.BeginMM <= a.EndMM).Where(a => (mm + AlertSearchRadius) >= a.BeginMM && (mm - AlertSearchRadius) <= a.EndMM).OrderByDescending(a => a.DateGenerated).Take(1); var spdHarmDecrAlerts = spdHarmRoadwayAlerts.Where(a => a.BeginMM > a.EndMM).Where(a => (mm - AlertSearchRadius) <= a.BeginMM && (mm + AlertSearchRadius) >= a.EndMM).OrderByDescending(a => a.DateGenerated).Take(1); var spdHarmApplicableAlerts = spdHarmIncrAlerts.Union(spdHarmDecrAlerts).ToList(); try { ExtractedTIM timMessage = new ExtractedTIM(); timMessage.setPacketId(TimAgencyId, DateTime.Now); List <ExtractedTimFrame> frames = new List <ExtractedTimFrame>(); foreach (var alert in qWarnApplicableAlerts) { double startMM = alert.BOQMMLocation; double endMM = (double)alert.FOQMMLocation; double length = Math.Abs(endMM - startMM); int time = -1; if (alert.SpeedInQueue != null && alert.SpeedInQueue != 0) { time = (int)(length * 60 / (short)alert.SpeedInQueue); } int duration = alert.ValidityDuration == null ? AlertDefaultDuration : (int)alert.ValidityDuration; ExtractedTimFrame frame = BuildAlertFrame(roadwayid, String.Format("q,{0:F1},{1},{2}", length, time, "Q-WARN: In Queue"), alert.DateGenerated, duration, startMM, endMM); if (frame.getAlertPathCount() > 0) { frames.Add(frame); } } foreach (var alert in qWarnAheadApplicableAlerts) { double endMM = alert.BOQMMLocation; double startMM; if (alert.BOQMMLocation > alert.FOQMMLocation) { startMM = endMM + QWarnAheadDistance; } else { startMM = endMM - QWarnAheadDistance; } double length = Math.Abs(endMM - startMM); int time = -1; if (alert.SpeedInQueue != null && alert.SpeedInQueue != 0) { time = (int)(length * 60 / (short)alert.SpeedInQueue); } int duration = alert.ValidityDuration == null ? AlertDefaultDuration : (int)alert.ValidityDuration; ExtractedTimFrame frame = BuildAlertFrame(roadwayid, String.Format("a,{0:F1},{1},{2}", length, time, "Q-WARN: Queue Ahead"), alert.DateGenerated, duration, startMM, endMM); if (frame.getAlertPathCount() > 0) { frames.Add(frame); } } foreach (var alert in spdHarmApplicableAlerts) { double startMM = alert.BeginMM; double endMM = (double)alert.EndMM; int duration = alert.ValidityDuration == null ? AlertDefaultDuration : (int)alert.ValidityDuration; ExtractedTimFrame frame = BuildAlertFrame(roadwayid, String.Format("s,{0},{1}", alert.RecommendedSpeed, alert.Justification), alert.DateGenerated, duration, startMM, endMM); if (frame.getAlertPathCount() > 0) { frames.Add(frame); } } timMessage.setFrames(frames.ToArray()); var rawTimMessageContent = timMessage.generateASN(); TimMessage rTimMessage = new TimMessage(); rTimMessage.payload = string.Concat(Array.ConvertAll(rawTimMessageContent, b => b.ToString("X2"))); return(this.Request.CreateResponse <TimMessage>(HttpStatusCode.OK, rTimMessage)); } catch (Exception e) { return(this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Error generating TIM Message", e)); } } }