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;
 }
Exemple #5
0
        /// <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);
 }