def get_next_location_details(self, direction, x, y): """ params: current user's direction (relative to north 0~360d), current x & y pos return: distance to next loc, direction to next loc (relative to user) & next loc's node """ nextLocNode = self.get_next_location(x, y) if self.nextLoc and self.nextLoc['nodeName'] in self.reachedLoc: self.prevLoc = self.nextLoc self.nextLoc = nextLocNode dist = Map.get_distance(nextLocNode["x"], x, nextLocNode["y"], y) northAt = Map.get_north_at(self.building, self.level) userDir = direction + northAt # relative to map userDir = userDir % 360 movingDir = Map.get_direction(x, nextLocNode["x"], y, nextLocNode["y"]) # relative to map relativeDir = movingDir - userDir # if relativeDir > 0, it's at user's rhs, else lhs if relativeDir > 180: relativeDir -= 360 if relativeDir < -180: relativeDir += 360 return relativeDir, dist, nextLocNode
def is_reach_node(self, node, x, y): """current x, and current y""" distance = Map.get_distance(node["x"], x, node["y"], y) if distance <= Navigation.REACHED_RANGE: self.reachedLoc.append(node["nodeName"]) return True else: return False
def get_next_location(self, x, y): """ params: current x, and current y get the nearest node, and based on it, decide the next location """ route = self.get_route() routeLength = len(route) # base cases: if routeLength == 1: return Map.get_node_by_location_name(self.building, self.level, route[0]) elif routeLength == 2: return Map.get_node_by_location_name(self.building, self.level, route[1]) minDist = sys.maxint minDistNode = {} routeIdxOfMinDistNode = -1 # get the nearest node idx = 0 for location_name in route: node = Map.get_node_by_location_name(self.building, self.level, location_name) distance = Map.get_distance(node["x"], x, node["y"], y) if distance < minDist: minDist = distance minDistNode = node routeIdxOfMinDistNode = idx idx += 1 # decide the next location to return if routeIdxOfMinDistNode == 0: # if the nearest node is at the start point # return next node return Map.get_node_by_location_name(self.building, self.level, route[1]) elif routeIdxOfMinDistNode == routeLength - 1: # if is at the end point # return end node return minDistNode else: # is at point between start & end # prevNode ----- minDistNode (nearest node) ----- nextNode prevNode = Map.get_node_by_location_name(self.building, self.level, route[routeIdxOfMinDistNode - 1]) nextNode = Map.get_node_by_location_name(self.building, self.level, route[routeIdxOfMinDistNode + 1]) prevDist = Map.get_distance(prevNode["x"], x, prevNode["y"], y) nextDist = Map.get_distance(nextNode["x"], x, nextNode["y"], y) if nextDist <= prevDist: # if nearer to the next node if minDistNode["nodeName"] in self.reachedLoc: return nextNode else: return minDistNode else: # nextDist > prevDist -- nearer to the previous node if self.is_reach_node(minDistNode, x, y): # already reached the nearest node # return next node return nextNode else: # else return the nearest node if minDistNode["nodeName"] in self.reachedLoc: return nextNode else: return minDistNode