/// <summary> /// Used to pull all TrackPoints that are assigned to a Route on a specific date /// </summary> /// <param name="roleId">Used to find the Business Account</param> /// <param name="routeId">The Id of the Route to pull Track Points for</param> /// <returns>A Queryable list of TrackPoints</returns> public IQueryable<TrackPoint> Get(Guid roleId, Guid routeId) { var connectionString = AzureServerHelpers.StorageConnectionString; //Get the storage account from Azure var storageAccount = CloudStorageAccount.Parse(connectionString); //Setup the service context for the TrackPointsHistory tables var serviceContext = new TrackPointsHistoryContext(storageAccount.TableEndpoint.ToString(), storageAccount.Credentials); var businessAccount = CoreEntitiesContainer.Owner(roleId).FirstOrDefault(); if (businessAccount == null) throw Request.NotAuthorized(); //Table Names must start with a letter. They also must be alphanumeric. http://msdn.microsoft.com/en-us/library/windowsazure/dd179338.aspx var tableName = businessAccount.Id.TrackPointTableName(); //Gets all objects from the Azure table specified on the date requested and returns the result var trackPoints = serviceContext.CreateQuery<TrackPointsHistoryTableDataModel>(tableName) .Where(tp => tp.RouteId == routeId) //The following allows us to get more than 1000 rows at a time .AsTableServiceQuery().Execute().OrderBy(tp => tp.CollectedTimeStamp).Select(TrackPoint.ConvertToModel).ToArray(); var filteredTrackPoints = new List<TrackPoint>(); //Filter out erroneous points for (int i = 0; i < trackPoints.Count(); i++) { var current = trackPoints[i]; var previous = trackPoints.ElementAtOrDefault(i - 1); if (previous != null) { var timeDelta = current.CollectedTimeStamp.Subtract(previous.CollectedTimeStamp); if (Erroneous(previous, current, timeDelta)) continue; var next = trackPoints.ElementAtOrDefault(i + 1); if (next != null && next.CollectedTimeStamp.Subtract(current.CollectedTimeStamp) < TimeSpan.FromSeconds(5)) { //TODO log this and figure out why the server is saving these trackpoints continue; } //for debugging erroneous points //var distanceToErroneous = GeoLocationTools.VincentyDistanceFormula(current, new GeoLocation(20.899650842339007, -156.41764283180234)); //if (distanceToErroneous < .001) //clicking on the map has a certain amount of inaccuracy //{ // var next = trackPoints.ElementAtOrDefault(i + 1); // var nextTimeDelta = next.CollectedTimeStamp.Subtract(current.CollectedTimeStamp); // var nextDistanceDelta = GeoLocationTools.VincentyDistanceFormula(current, next) * 1000.0; // var nextVelocity = nextDistanceDelta / nextTimeDelta.TotalSeconds; //} } filteredTrackPoints.Add(current); } return filteredTrackPoints.AsQueryable(); }
/// <summary> /// Populates HistoricalTrackPoints design data on the Azure tables. /// </summary> public static void CreateHistoricalTrackPoints() { var coreEntitiesContainer = new CoreEntitiesContainer(); var businessAccountIds = coreEntitiesContainer.Parties.OfType<BusinessAccount>().Select(ba => ba.Id); foreach (var businessAccountId in businessAccountIds) { var tableName = businessAccountId.TrackPointTableName(); var storageAccount = CloudStorageAccount.Parse(AzureServerHelpers.StorageConnectionString); var serviceContext = new TrackPointsHistoryContext(storageAccount.TableEndpoint.ToString(), storageAccount.Credentials); var tableClient = storageAccount.CreateCloudTableClient(); //Create the empty table once again tableClient.CreateTableIfNotExist(tableName); var serviceDate = DateTime.UtcNow; var routes = coreEntitiesContainer.Routes.Where(r => r.Date == serviceDate.Date && r.OwnerBusinessAccountId == businessAccountId).OrderBy(r => r.Id); //Do not setup design data for Test or Release #if DEBUG #region Setup Design Data for Historical Track Points var numberOfRoutes = routes.Count(); var count = 1; foreach (var route in routes) { var routeNumber = count % numberOfRoutes; switch (routeNumber) { //This would be the 4th, 8th, etc case 0: var employees = route.Employees; foreach (var employee in employees) { var latitude = 40.4599; var longitude = -86.9309; //Sets timeStamp to be 9:00 AM yesterday var timeStamp = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, 9, 0, 0); for (var totalCount = 1; totalCount <= 3; totalCount++) { var partitionKey = Guid.NewGuid().ToString(); for (var innerCount = 1; innerCount < 99; innerCount++) { //Create the object to be stored in the Azure table var newTrackPoint = new TrackPointsHistoryTableDataModel(partitionKey, Guid.NewGuid().ToString()) { EmployeeId = employee.Id, VehicleId = null, RouteId = route.Id, Latitude = latitude, Longitude = longitude, CollectedTimeStamp = timeStamp, Accuracy = 1 }; latitude = latitude + .001; longitude = longitude + .001; timeStamp = timeStamp.AddSeconds(30); //Push to Azure Table serviceContext.AddObject(tableName, newTrackPoint); } serviceContext.SaveChangesWithRetries(SaveChangesOptions.Batch); } } break; //This would be the 1st, 5th, etc case 1: employees = route.Employees; foreach (var employee in employees) { var latitude = 40.4599; var longitude = -86.9309; //Sets timeStamp to be 9:00 AM yesterday var timeStamp = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, 9, 0, 0); for (var totalCount = 1; totalCount <= 3; totalCount++) { var partitionKey = Guid.NewGuid().ToString(); for (var innerCount = 1; innerCount <= 99; innerCount++) { //Create the object to be stored in the Azure table var newTrackPoint = new TrackPointsHistoryTableDataModel(partitionKey, Guid.NewGuid().ToString()) { EmployeeId = employee.Id, VehicleId = null, RouteId = route.Id, Latitude = latitude, Longitude = longitude, CollectedTimeStamp = timeStamp, Accuracy = 1 }; latitude = latitude - .001; longitude = longitude + .001; timeStamp = timeStamp.AddSeconds(30); //Push to Azure Table serviceContext.AddObject(tableName, newTrackPoint); } serviceContext.SaveChangesWithRetries(SaveChangesOptions.Batch); } } break; //This would be the 2nd, 6th, etc case 2: employees = route.Employees; foreach (var employee in employees) { var latitude = 40.4599; var longitude = -86.9309; //Sets timeStamp to be 9:00 AM yesterday var timeStamp = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, 9, 0, 0); for (var totalCount = 1; totalCount <= 3; totalCount++) { var partitionKey = Guid.NewGuid().ToString(); for (var innerCount = 1; innerCount <= 99; innerCount++) { //Create the object to be stored in the Azure table var newTrackPoint = new TrackPointsHistoryTableDataModel(partitionKey, Guid.NewGuid().ToString()) { EmployeeId = employee.Id, VehicleId = null, RouteId = route.Id, Latitude = latitude, Longitude = longitude, CollectedTimeStamp = timeStamp, Accuracy = 2 }; latitude = latitude + .001; longitude = longitude - .001; timeStamp = timeStamp.AddSeconds(30); //Push to Azure Table serviceContext.AddObject(tableName, newTrackPoint); } serviceContext.SaveChangesWithRetries(SaveChangesOptions.Batch); } } break; //This would be the 3rd, 7th, etc case 3: employees = route.Employees; foreach (var employee in employees) { var latitude = 40.4599; var longitude = -86.9309; //Sets timeStamp to be 9:00 AM yesterday var timeStamp = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, 9, 0, 0); for (var totalCount = 1; totalCount <= 3; totalCount++) { var partitionKey = Guid.NewGuid().ToString(); for (var innerCount = 1; innerCount <= 99; innerCount++) { //Create the object to be stored in the Azure table var newTrackPoint = new TrackPointsHistoryTableDataModel(partitionKey, Guid.NewGuid().ToString()) { EmployeeId = employee.Id, VehicleId = null, RouteId = route.Id, Latitude = latitude, Longitude = longitude, CollectedTimeStamp = timeStamp, Accuracy = 3 }; latitude = latitude - .001; longitude = longitude - .001; timeStamp = timeStamp.AddSeconds(30); //Push to Azure Table serviceContext.AddObject(tableName, newTrackPoint); } serviceContext.SaveChangesWithRetries(SaveChangesOptions.Batch); } } break; } count++; } #endregion #endif } }
/// <summary> /// Takes a ModelTrackPoint and pushed it to the AzureTables /// </summary> /// <param name="currentBusinessAccount">The current BusinessAccount</param> /// <param name="trackPoint">The Model TrackPoint to be pushed to AzureTables</param> /// <param name="employee">The employee</param> /// <param name="routeId">The Id of the Route that the vehicle or employee are currently on</param> private void PushTrackPointToAzure(Core.Models.CoreEntities.BusinessAccount currentBusinessAccount, TrackPoint trackPoint, Core.Models.CoreEntities.Employee employee, Guid routeId) { //Get the storage account information from Azure var storageAccount = CloudStorageAccount.Parse(AzureServerHelpers.StorageConnectionString); //Create the Service Context for the TrackPointsHistory Tables var serviceContext = new TrackPointsHistoryContext(storageAccount.TableEndpoint.ToString(), storageAccount.Credentials); var tableName = CheckCreateTrackPointTable(storageAccount, currentBusinessAccount); //Create the object to be stored in the Azure table var newTrackPoint = new TrackPointsHistoryTableDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString()) { EmployeeId = employee.Id, VehicleId = new Guid(), RouteId = routeId, Latitude = (double?)trackPoint.Latitude, Longitude = (double?)trackPoint.Longitude, CollectedTimeStamp = trackPoint.CollectedTimeStamp, Accuracy = trackPoint.Accuracy }; //Push to Azure Table serviceContext.AddObject(tableName, newTrackPoint); //Saves the Tables serviceContext.SaveChangesWithRetries(); }