public WeightedLocation(Location loc, double weight, Floorplan floorplan) { Location = loc; Weight = weight; Floorplan = floorplan; }
/// <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 startX, int startY, int endX, int endY, Floorplan startFloorPlan, Floorplan endFloorPlan) { int startFloor = startFloorPlan.Floor; int endFloor = endFloorPlan.Floor; // The route object will contain the final route, if one exists RouteDto route = new RouteDto(); if (_bluePrint == null) { return route.pathfindingError(); } // Get map of start floor through api. // If something goes wrong, return a fail-code route bool[,] startFloorMap = getFloorMap(startFloor, _bluePrint); if (startFloorMap == null) { return route.pathfindingError(); } // API call for endFloor map // (needed in places of different scope below) bool[,] endFloorMap = null; if (startFloor != endFloor) { endFloorMap = getFloorMap(endFloor, _bluePrint); if (endFloorMap == null) { return route.pathfindingError(); } } // BEGIN PATHFINDING ///////////////// if (startFloor == endFloor) { AStarSearch searchPath = new AStarSearch(startFloorMap).run(startX, startY, endX, endY); if (searchPath.hasSolution()) { // Create the event for the path and add it to our route lastFloorGridWidth = searchPath.gridLengthX; lastFloorGridHeight = searchPath.gridLengthY; return route.addPath(startFloor, searchPath.Solution.ToList()); } // falls out to third-tier search } else { if (endFloorMap == null) { return route.pathfindingError(); } // API call searching for all "vertical paths" (VPs) from startFloor directly to endFloor // var directPois = _bluePrint.NavigationalPois // .Where(v => v.Locations.Any(l => l.FloorPlan.Floor == startFloor) && v.Locations.Any(asd => asd.FloorPlan.Floor == endFloor)) // .ToList(); var directPois = _bluePrint.GetDirectNavPois(startFloor, endFloor); if (directPois != null && directPois.Count > 0) { // Create the search objs here to be reused. Prevents duplicatoin of weighted-grid work. AStarSearch search1 = new AStarSearch(startFloorMap); AStarSearch search2 = new AStarSearch(endFloorMap); // Here we are looking for a valid path using only one stairs, elevator, etc. foreach (var v in directPois) { // start floor var fp1 = v.Location; // FloorPlanLocation fp1 = v.Locations.Where(x => x.FloorPlan.Floor == startFloor).FirstOrDefault(); int vertX1 = (int) (fp1.X*startFloorPlan.ImageDataWidth); int vertY1 = (int) (fp1.Y*startFloorPlan.ImageDataHeight); // find path from user position to the "stairs" search1.run(startX, startY, vertX1, vertY1); // if we can't get to the "stairs" from here, lets try the next way up if (!search1.hasSolution()) { continue; } // end floor var fp2 = v.Location; // FloorPlanLocation fp2 = v.Locations.Where(x => x.FloorPlan.Floor == endFloor).FirstOrDefault(); int vertX2 = (int) (fp2.X*endFloorPlan.ImageDataWidth); int vertY2 = (int) (fp2.Y*endFloorPlan.ImageDataHeight); // find path from "stairs" to the ending position search2.run(vertX2, vertY2, endX, endY); // if we can't get to the "stairs" from here, we do not want to get to the return statement if (!search2.hasSolution()) { continue; } lastFloorGridWidth = search2.gridLengthX; lastFloorGridHeight = search2.gridLengthY; // Create solution return route .addPath(startFloor, search1.Solution.ToList()) .addVerticalTransisiton(v.Type, new CoordinateDto(vertX1, vertY1, search1.gridLengthX, search1.gridLengthY), startFloor, endFloor) .addPath(endFloor, search2.Solution.ToList()); } // falls out to third-tier search } } // the infamous third-tier search return route; }