public static FloorPlan Generate(Blueprint bp, int beaconCount, int poiCount) { var fp = Generate(); fp.Beacons = BeaconGenerator.GenerateMany(beaconCount, FloorPlanLocationGenerator.Generate(fp)); fp.PointsOfInterest = PoiGenerator.GenerateMany(poiCount, FloorPlanLocationGenerator.Generate(fp)); return fp; }
public static ICollection<FloorPlan> GenerateMany(int count, Blueprint bp, int beaconCount, int poiCount) { var list = new List<FloorPlan>(); for (var i = 0; i < count; i++) { list.Add(Generate(bp, beaconCount, poiCount)); } return list; }
public void OnTestSetup() { _host = new ServiceTestAppHost(); _host.Init(); _host.Start(ServiceTestAppHost.BaseUrl); _client = new JsonServiceClient(ServiceTestAppHost.BaseUrl); IocBox.Kernel = new StandardKernel(new RealDomainModule(), new RealInfrastructureModule()); string pass; _testUser = DbDataGenerator.AddUserToDatabase(out pass); _testBlueprint = DbDataGenerator.AddBlueprintToDatabase(_testUser.Id); _client.Send(new Auth {UserName = _testUser.Email, Password = pass}); }
private static bool IsBluePrintOwner(Blueprint blueprint, int userId) { return blueprint != null && blueprint.UserId == userId; }
/// <summary> /// Fullfills pathfinding requests by returning a Route object. /// </summary> /// <param name="startX"></param> /// <param name="endX"></param> /// <param name="startY"></param> /// <param name="endY"></param> /// <param name="startFloor"></param> /// <param name="endFloor"></param> /// <returns></returns> public RouteDto getPath(int startBuildingId, int endBuildingId, double startPercentX, double startPercentY, double endPercentX, double endPercentY, int startFloor, int endFloor) { using (BlueprintUnitOfWork uow = new BlueprintUnitOfWork()) { _startBluePrint = uow.BluePrints.FirstOrDefault(b => b.Id == startBuildingId); // The start cannot be null if (_startBluePrint == null) { return new RouteDto().pathfindingError(); } FloorPlan startFloorPlan = _startBluePrint.FloorPlans.FirstOrDefault(fp => fp.Floor == startFloor); FloorPlan endFloorPlan = startFloorPlan; if (startBuildingId == endBuildingId && startFloor != endFloor) { endFloorPlan = _startBluePrint.FloorPlans.FirstOrDefault(fp => fp.Floor == endFloor); } int startGridWidth = startFloorPlan.ImageDataWidth; int startGridHeight = startFloorPlan.ImageDataHeight; int endGridWidth = endFloorPlan.ImageDataWidth; int endGridHeight = endFloorPlan.ImageDataHeight; int startX = (int) (startGridWidth * startPercentX); int startY = (int) (startGridHeight * startPercentY); int endX = (int) (endGridWidth * endPercentX); int endY = (int) (endGridHeight * endPercentY); if (startBuildingId != endBuildingId) { _endBluePrint = uow.BluePrints.FirstOrDefault(b => b.Id == endBuildingId); endFloorPlan = _endBluePrint.FloorPlans.FirstOrDefault(fp => fp.Floor == endFloor); endGridWidth = endFloorPlan.ImageDataWidth; endGridHeight = endFloorPlan.ImageDataHeight; endX = (int) (endGridWidth * endPercentX); endY = (int) (endGridHeight * endPercentY); } // If the ending BluePrint is null, that only means that there is no second // building to navigate to. So we will just pathfind within the one building. if (_endBluePrint == null) { return new BluePrintPathFinder(uow, _startBluePrint).getPath(startX, startY, endX, endY, startFloorPlan, endFloorPlan); } //** The fun part! Here we will need to do a GPS (outdoor) transition between two buildings. **// // Get exit POIs for start and end buildings var startBldgExits = _startBluePrint.NavigationalPois .Where(poi => poi.Type == NavType.Exit) .Select(poi => poi.Locations.FirstOrDefault()) .ToList(); var endBldgExits = _endBluePrint.NavigationalPois .Where(poi => poi.Type == NavType.Exit) .Select(poi => poi.Locations.FirstOrDefault()) .ToList(); //** Get the distances between the exits of the buildings to find the closest ones **// double smallestDistance = double.PositiveInfinity; FloorPlanLocation startLoc = null; FloorPlanLocation endLoc = null; foreach (FloorPlanLocation s in startBldgExits) { foreach (FloorPlanLocation e in endBldgExits) { double distance = GeoUtils.getDistance(s.Latitude, s.Longitude, e.Latitude, e.Longitude); if (distance < smallestDistance) { smallestDistance = distance; startLoc = s; endLoc = e; } } } //** Add exit locations to list in order of priorty to consider for pathfinding **// var starts = new List<WeightedLocation>(); var ends = new List<WeightedLocation>(); // Set each possible start-exit location with a weight in relation to the ideal end-exit location foreach (FloorPlanLocation loc in startBldgExits) { double distance = GeoUtils.getDistance(loc.Latitude, loc.Longitude, endLoc.Latitude, endLoc.Longitude); starts.Add(new WeightedLocation(loc, distance)); } // Set each possible end-exit location with a weight in relation to the ideal start-exit location foreach (FloorPlanLocation loc in endBldgExits) { double distance = GeoUtils.getDistance(loc.Latitude, loc.Longitude, startLoc.Latitude, startLoc.Longitude); ends.Add(new WeightedLocation(loc, distance)); } // sort the lists into priority order according to weight starts.Sort((geo1, geo2) => geo1.Weight.CompareTo(geo2.Weight)); ends.Sort((geo1, geo2) => geo1.Weight.CompareTo(geo2.Weight)); //** Find valid routes from within each building to an exit **// WeightedLocation outidePathStarts = starts.First(); WeightedLocation outidePathEnds = ends.First(); BluePrintPathFinder startPathFinder = new BluePrintPathFinder(uow, _startBluePrint); BluePrintPathFinder endPathFinder = new BluePrintPathFinder(uow, _endBluePrint); RouteDto startRoute = null; RouteDto endRoute = null; // Get and validate the startPath foreach (WeightedLocation loc in starts) { startRoute = startPathFinder.getPath(startX, startY, (int) (loc.location.XPos * startGridWidth), (int) (loc.location.YPos * startGridHeight), startFloorPlan, loc.location.FloorPlan); if (startRoute != null && startRoute.code == RouteDto.CODE_SUCCESS) { startLoc = loc.location; break; } } if (startRoute == null) { return new RouteDto().pathfindingError(); } if (startRoute.code != RouteDto.CODE_SUCCESS) { return startRoute; } // Get and validate the end path foreach (WeightedLocation loc in ends) { endRoute = endPathFinder.getPath((int) (loc.location.XPos * endGridWidth), (int) (loc.location.YPos * endGridHeight), endX, endY, loc.location.FloorPlan, endFloorPlan); if (endRoute != null && endRoute.code == RouteDto.CODE_SUCCESS) { endLoc = loc.location; break; } } if (endRoute == null) { return new RouteDto().pathfindingError(); } if (endRoute.code != RouteDto.CODE_SUCCESS) { return endRoute; } // Get the Google path GoogJson resp = GoogleMapsApi.getDirections(startLoc.Latitude, startLoc.Longitude, endLoc.Latitude, endLoc.Longitude, GoogleMapsApi.MODE_WALKING); if (resp.Routes.FirstOrDefault() == null) { return new RouteDto().pathfindingError(); } RouteDto outdoorRoute = new RouteDto() .addOutdoorTransisiton(NavType.Walking, new CoordinateDto((int) (startLoc.XPos * startGridWidth), (int) (startLoc.YPos * startGridHeight), startPathFinder.lastFloorGridWidth, startPathFinder.lastFloorGridHeight), startLoc.FloorPlan.Floor); outdoorRoute.addEvent( new RouteEvent() .setOutdoor(resp.Routes.FirstOrDefault().Overview_Polyline.Points, _startBluePrint.Id, _endBluePrint.Id, startLoc.Latitude, startLoc.Longitude, endLoc.Latitude, endLoc.Longitude)); return startRoute.append(outdoorRoute).append(endRoute); } }
private void Equals(Blueprint expected, BeaconDto actual) { Assert.AreEqual(expected.Id, actual.BluePrintId); Assert.AreEqual(expected.Name, actual.BluePrintName); }
/// <summary> /// Constructs a new PathFinder initialized with the desired building ID /// </summary> /// <param name="buildingId"></param> public BluePrintPathFinder(BlueprintUnitOfWork uow, Blueprint bluePrint) { _bluePrint = bluePrint; _uow = uow; }
/// <summary> /// Queries the Blueprint db object to get the data-map of a given floor /// </summary> /// <param name="floor"></param> /// <param name="bp"></param> /// <returns></returns> private bool[,] getFloorMap(int floor, Blueprint bp) { try { var fp = bp.FloorPlans.FirstOrDefault(f => f.Floor == floor); var width = fp.ImageDataWidth; var height = fp.ImageDataHeight; bool[,] result = new bool[height, width]; string path = string.Format("/bp{0}.fp{1}.floor_{2}.txt", bp.Id, fp.Id, fp.Floor); string url = string.Format(Defs.DataGridUrl, path); // TODO: Using the WebClient is for testing off of the server's file system. // SOme performance could be gained if we use a file stream and absolute path. using (Stream fs = new WebClient().OpenRead(url)) using (BufferedStream bs = new BufferedStream(fs)) using (StreamReader sr = new StreamReader(bs)) { // Read the file line by line and populate the data grid string line; int y = 0; while ((line = sr.ReadLine()) != null) { int x = 0; foreach (char c in line) { if (c == ' ') { x = x; } // set a true value if it is a space result[y, x] = c == ' '; x++; } y++; } } return result; } catch (Exception) { return null; } }
private void Equal(Blueprint expected, BluePrintDto actual) { Assert.AreEqual(expected.Name, actual.Name); Assert.AreEqual(expected.Country, actual.Country); Assert.AreEqual(expected.City, actual.City); Assert.AreEqual(expected.State, actual.State); Assert.AreEqual(expected.Region, actual.Region); Assert.AreEqual(expected.Id, actual.Id); }