private void UpdateWeatherFromTable(Location pos, double radius, TimeSpan delta) { if (!tableinitialized) { var connectionString = ConfigurationManager.AppSettings["Microsoft.Storage.ConnectionString"]; if (string.IsNullOrEmpty(connectionString)) { Console.WriteLine("Did not find table storage connection string in appsettings (app.config)"); return; } CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); // Create service client for credentialed access to the Table service. tableClient = new CloudTableClient(storageAccount.TableEndpoint, storageAccount.Credentials); table = tableClient.GetTableReference("airtable"); tableinitialized = true; } List<string> results = new List<string>(); DateTime now = DateTime.Now; DateTime since = now.Subtract(delta); DateTimeOffset dto = since; string partitionFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "airtelemetry"); string sinceFilter = TableQuery.GenerateFilterConditionForDate("dto", QueryComparisons.GreaterThan, since); string finalFilter = TableQuery.CombineFilters(partitionFilter, TableOperators.And, sinceFilter); TableQuery<AirTelemetry> query = new TableQuery<AirTelemetry>().Where(finalFilter); /* clearly not the most efficient way to do this but ok for a POC */ foreach(AirTelemetry atrec in table.ExecuteQuery(query)) { Console.WriteLine(atrec.airline +" " + atrec.flight); if(Haversine.InRange(pos, atrec.lat,atrec.lng, radius)) { if(atrec.lightning>20.0) { WeatherEvent we = new WeatherEvent(WeatherEventTypes.TSTORM, atrec.dto, new Location(atrec.lat, atrec.lng)); weatherevents.Add(we); } if (atrec.ice == 5.0) { WeatherEvent we = new WeatherEvent(WeatherEventTypes.LIGHT_ICE, atrec.dto, new Location(atrec.lat, atrec.lng)); weatherevents.Add(we); } if (atrec.ice == 10.0) { WeatherEvent we = new WeatherEvent(WeatherEventTypes.MODERATE_ICE, atrec.dto, new Location(atrec.lat, atrec.lng)); weatherevents.Add(we); } if (atrec.ice > 10.0) { WeatherEvent we = new WeatherEvent(WeatherEventTypes.HEAVY_ICE, atrec.dto, new Location(atrec.lat, atrec.lng)); weatherevents.Add(we); } if(atrec.windspeed==20.0 ) { WeatherEvent we = new WeatherEvent(WeatherEventTypes.MODERATE_TURB, atrec.dto, new Location(atrec.lat, atrec.lng)); weatherevents.Add(we); } if (atrec.windspeed > 20.0) { WeatherEvent we = new WeatherEvent(WeatherEventTypes.HEAVY_TURB, atrec.dto, new Location(atrec.lat, atrec.lng)); weatherevents.Add(we); } if(atrec.windshear>=15.0 && atrec.windshear<=25.0) { WeatherEvent we = new WeatherEvent(WeatherEventTypes.MODERATE_SHEAR, atrec.dto, new Location(atrec.lat, atrec.lng)); weatherevents.Add(we); } if (atrec.windshear > 20.0) { WeatherEvent we = new WeatherEvent(WeatherEventTypes.HEAVY_SHEAR, atrec.Timestamp, new Location(atrec.lat, atrec.lng)); weatherevents.Add(we); } } } return; }
async Task TrackFlight(AirTelemetry AT, Location origin, Location destination, double miles) { string json=""; var eventHubConnectionString = GetEventHubConnectionString(); var eventHubClient = EventHubClient.CreateFromConnectionString(eventHubConnectionString, eventHubName); int runningMileCount = 0; int updateWeatherInverval = 200; int updateWeatherRadius = 300; /* how many miles we go per tick */ int mileageIncrement = 30; Pushpin pin = new Pushpin(); Label infoLabel = new Label(); MapLayer InfoLayer = new MapLayer(); AT.RowKey += DateTime.Now.ToShortDateString(); /* get rid of illegal characters in row key */ AT.RowKey = Regex.Replace(AT.RowKey, @"[\ /?#]", ""); MapPolyline polyline = new MapPolyline(); polyline.Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Blue); polyline.StrokeThickness = 5; polyline.Opacity = 0.7; /* pre-plot the course so that we can draw the flight path on the map. we recalculate the bearing every * 100 miles (could/should be configurable) to get a true Great Circle route. */ Location prev = origin; Location nxtl; double hdg = AT.heading; polyline.Locations=new LocationCollection(); polyline.Locations.Add(origin); int j; for (j = 2; ;j++ ) { nxtl = Haversine.PositionDistanceFromOrigin(prev, mileageIncrement / 0.00062137, hdg); polyline.Locations.Add(nxtl); hdg = Haversine.Bearing(nxtl, destination); prev = nxtl; if (Haversine.InRange(nxtl, destination.Latitude, destination.Longitude, 100)) { polyline.Locations.Add(destination); break; } } string rkey = AT.RowKey; AT.lat = origin.Latitude; AT.lng = origin.Longitude; UpdateMap(AT, pin, polyline, InfoLayer); UpdateWeatherFromTable(origin, 300, new TimeSpan(3, 0, 0)); int i; for (i = 0; i <= polyline.Locations.Count; i++) { await Task.Delay(2000); try { AT.RowKey = rkey +'-'+ i.ToString(); /* row key must be unique or will overwrite existing */ FlightMap.Children.Clear(); FlightMap.Children.Add(polyline); InfoLayer.Children.Clear(); /* we have two time stamps. the first is inherited from TableEntity and normally should not be used by applications. We * initialize it here because Stream Analytics will barf on an illegal data (dates must be greater than * 12:00 midnight, January 1, 1601 A.D. (C.E.), UTC.). We do not use the inherited time stamp after this; this is what * AT.dto is for */ AT.Timestamp = DateTime.Now; AT.dto = DateTimeOffset.Now; AT.inflight = "true"; /* send distance in meters */ Location p = Haversine.PositionDistanceFromOrigin(new Location(AT.lat, AT.lng), mileageIncrement / 0.00062137, AT.heading); AT.lat = p.Latitude; AT.lng = p.Longitude; double b2 = Haversine.Bearing(p, destination); AT.heading = b2; /* altitude in meters */ if (i < 5) AT.altitude = 10000 / (6 - (i + 1)); /* ascending */ else if ((polyline.Locations.Count - i) < 5) AT.altitude = 10000 / (polyline.Locations.Count+1 - i); /* descending */ else AT.altitude = 10000; /* initialize the data structure */ AT.ice = 0.0; AT.windspeed = 0.0; AT.windshear = 0.0; AT.lightning = 0.0; /* encode weather conditions */ if(ltice) { AT.ice = 5.0; WeatherEvent we = new WeatherEvent(WeatherEventTypes.LIGHT_ICE, DateTime.Now, p); weatherevents.Add(we); ltice = false; } else if(mdice) { AT.ice = 10.0; WeatherEvent we = new WeatherEvent(WeatherEventTypes.MODERATE_ICE, DateTime.Now, p); weatherevents.Add(we); mdice = false; } else if (hvice) { AT.ice = 20.0; WeatherEvent we = new WeatherEvent(WeatherEventTypes.HEAVY_ICE, DateTime.Now, p); weatherevents.Add(we); hvice = false; } if(mdtub) { AT.windspeed = 20.0; WeatherEvent we = new WeatherEvent(WeatherEventTypes.MODERATE_TURB, DateTime.Now, p); weatherevents.Add(we); mdtub = false; } else if(hvtub) { AT.windspeed = 40.0; WeatherEvent we = new WeatherEvent(WeatherEventTypes.HEAVY_TURB, DateTime.Now, p); weatherevents.Add(we); hvtub = false; } if(mdshr) { AT.windshear = 20.0; WeatherEvent we = new WeatherEvent(WeatherEventTypes.MODERATE_SHEAR, DateTime.Now, p); weatherevents.Add(we); mdshr = false; } else if(hvshr) { AT.windshear = 40.0; WeatherEvent we = new WeatherEvent(WeatherEventTypes.HEAVY_SHEAR, DateTime.Now, p); weatherevents.Add(we); hvshr = false; } if(tstrm) { AT.lightning = 50.0; WeatherEvent we = new WeatherEvent(WeatherEventTypes.TSTORM, DateTime.Now, p); weatherevents.Add(we); tstrm = false; } json = Newtonsoft.Json.JsonConvert.SerializeObject(AT); Console.WriteLine("{0} > Sending message: {1}", DateTime.Now.ToString(), json); FlightMap.Center.Latitude = p.Latitude; FlightMap.Center.Longitude = p.Longitude; FlightMap.Center.Altitude = AT.altitude; Location center = FlightMap.Center; double zoom = FlightMap.ZoomLevel; FlightMap.SetView(center, zoom); pin.Location = center; FlightMap.Children.Add(pin); infoLabel.Content = AT.airline + " " + AT.flight; InfoLayer.AddChild(infoLabel, center); WeatherImageLayer(InfoLayer); FlightMap.Children.Add(InfoLayer); UpdateFlightInfoBox(AT, false); if(Haversine.InRange(new Location(AT.lat, AT.lng), destination.Latitude,destination.Longitude,50)) break; await eventHubClient.SendAsync(new EventData(Encoding.UTF8.GetBytes(json))); runningMileCount += mileageIncrement; if(runningMileCount>=updateWeatherInverval) { runningMileCount = 0; weatherevents.Clear(); UpdateWeatherFromTable(new Location(AT.lat, AT.lng), updateWeatherRadius, new TimeSpan(3, 0, 0)); } } catch (Exception exception) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("{0} > Exception: {1}", DateTime.Now.ToString(), exception.Message); Console.ResetColor(); } } AT.arrival = DateTime.Now; AT.inflight = "false"; /* fudge the destination position */ AT.lat=FlightMap.Center.Latitude = destination.Latitude; AT.lng=FlightMap.Center.Longitude = destination.Longitude; FlightMap.Center.Altitude = AT.altitude; UpdateMap(AT, pin, polyline, InfoLayer); json = Newtonsoft.Json.JsonConvert.SerializeObject(AT); await eventHubClient.SendAsync(new EventData(Encoding.UTF8.GetBytes(json))); UpdateFlightInfoBox(AT, true); }