def basic_way_test(self): """Test basic Way creation and usage.""" first = (0.0, 0.0, 0.0) second = (1.0, 1.0, 100.0) third = (2.0, 2.0, 200.0) lle_list = [first, second, third] way = Way(points=lle_list) self.assertListEqual(way.points_lle, lle_list) self.assertEqual(way.point_count, 3) # check getting points by index self.assertEqual(way.get_point_by_index(0).getLLE(), first) self.assertEqual(way.get_point_by_index(1).getLLE(), second) self.assertEqual(way.get_point_by_index(2).getLLE(), third) # negative indexing should work the same as in a list self.assertEqual(way.get_point_by_index(-1).getLLE(), third) self.assertEqual(way.get_point_by_index(-2).getLLE(), second) self.assertEqual(way.get_point_by_index(-3).getLLE(), first) # out of bounds access should throw an index error with self.assertRaises(IndexError): way.get_point_by_index(100) with self.assertRaises(IndexError): way.get_point_by_index(-100) # route length or duration has not been set self.assertIsNone(way.length) self.assertIsNone(way.duration) # there should be no message points self.assertListEqual(way.message_points, []) self.assertEqual(way.message_point_count, 0)
def clear_test(self): """Test if the clear() methods of the Way class works correctly.""" # put some regular points to the way first first = (0.0, 0.0, 0.0) second = (1.0, 1.0, 100.0) third = (2.0, 2.0, 200.0) lle_list = [first, second, third] way = Way(points=lle_list) # add some message points point1 = Point(lat=50.0, lon=50.0, elevation=300.0, message="foo") point2 = Point(lat=75.0, lon=75.0, elevation=600.0, message="bar") way.add_message_point(point1) way.add_message_point(point2) # check there are points & message points self.assertEqual(way.point_count, 3) self.assertEqual(way.message_point_count, 2) self.assertTrue(len(way.points_lle) > 0) self.assertTrue(len(way.message_points) > 0) self.assertTrue(len(way.message_points_lle) > 0) # call the clear methods way.clear() way.clear_message_points() # check that the way is empty self.assertEqual(way.point_count, 0) self.assertEqual(way.message_point_count, 0) self.assertListEqual(way.points_lle, []) self.assertListEqual(way.message_points, []) self.assertListEqual(way.message_points_lle, [])
def search(self, waypoints, route_params=None, controller=DummyController()): routingStart = time.time() controller.status = "OSM Scout Server routing" try: route_type = "auto" # car directions are the default if route_params.routeMode == constants.ROUTE_BIKE: route_type = "bicycle" elif route_params.routeMode == constants.ROUTE_PEDESTRIAN: route_type = "pedestrian" locations = [] for waypoint in waypoints: location_dict = {'lat': waypoint.lat, 'lon': waypoint.lon} # include heading when available if waypoint.heading is not None: location_dict["heading"] = waypoint.heading locations.append(location_dict) params = { 'costing': route_type, 'directions_options': { 'language': route_params.language }, 'locations': locations } queryUrl = OSM_SCOUT_SERVER_ROUTING_URL + "json=" + json.dumps( params) reply = urlopen(queryUrl) if reply: # json in Python 3 really needs it encoded like this replyData = reply.read().decode("utf-8") jsonReply = json.loads(replyData) if "API version" in jsonReply and jsonReply[ 'API version'] == "libosmscout V1": route = Way.from_osm_scout_json(jsonReply) else: route = Way.from_valhalla(jsonReply) return RoutingResult(route, route_params, constants.ROUTING_SUCCESS, lookupDuration=time.time() - routingStart) except Exception: log.exception("OSM Scout Server routing: failed with exception")
def search(self, waypoints, route_params=None, controller=DummyController()): routingStart = time.time() if self._monav.data_path is not None: result = None try: if not self._monav.server_running: controller.status = "starting Monav routing server" self._monav.start_server() controller.status = "Monav offline routing in progress" log.info(route_params) result = self._monav.get_monav_directions( waypoints, route_params) controller.status = "Monav offline routing done" except Exception: log.exception('Monav route lookup failed') if result is None: # routing failed for unknown reasons return RoutingResult(None, route_params) if result.type == result.SUCCESS: # convert the Monav result to a Way object usable # for turn-by-turn navigation using the instruction # generator set in the Monav wrapper route = Way.from_monav_result(result) return RoutingResult(route, route_params, constants.ROUTING_SUCCESS, lookupDuration=time.time() - routingStart) elif result.type == result.LOAD_FAILED: return RoutingResult(None, route_params, constants.ROUTING_LOAD_FAILED) elif result.type == result.LOOKUP_FAILED: return RoutingResult(None, route_params, constants.ROUTING_LOOKUP_FAILED) elif result.type == result.ROUTE_FAILED: return RoutingResult(None, route_params, constants.ROUTING_ROUTE_FAILED) else: return RoutingResult(None, route_params) else: log.error("no Monav routing data - can't route") return RoutingResult(None, route_params, constants.ROUTING_NO_DATA)
def add_point_test(self): """Test adding regular points to a Way.""" first = (0.0, 0.0, 0.0) second = (1.0, 1.0, 100.0) third = (2.0, 2.0, 200.0) lle_list = [first, second, third] way = Way(points=lle_list) way.add_point(Point(lat=50.0, lon=50.0, elevation=300.0)) self.assertEqual(way.point_count, 4) self.assertListEqual(way.points_lle, [first, second, third, (50.0, 50.0, 300.0)]) way.add_point_lle(100.0, 100.0, 600.0) self.assertEqual(way.point_count, 5) self.assertListEqual( way.points_lle, [first, second, third, (50.0, 50.0, 300.0), (100.0, 100.0, 600.0)]) self.assertEqual( way.get_point_by_index(-1).getLLE(), (100.0, 100.0, 600.0))
def search(self, waypoints, route_params=None, controller=DummyController()): routingStart = time.time() if self._monav.data_path is not None: result = None try: if not self._monav.server_running: controller.status = "starting Monav routing server" self._monav.start_server() controller.status = "Monav offline routing in progress" log.info(route_params) result = self._monav.get_monav_directions(waypoints) controller.status = "Monav offline routing done" except Exception: log.exception('Monav route lookup failed') if result is None: # routing failed for unknown reasons return RoutingResult(None, route_params) if result.type == result.SUCCESS: # convert the Monav result to a Way object usable # for turn-by-turn navigation using the instruction # generator set in the Monav wrapper route = Way.from_monav_result(result) return RoutingResult(route, route_params, constants.ROUTING_SUCCESS, lookupDuration=time.time() - routingStart) elif result.type == result.LOAD_FAILED: return RoutingResult(None, route_params, constants.ROUTING_LOAD_FAILED) elif result.type == result.LOOKUP_FAILED: return RoutingResult(None, route_params, constants.ROUTING_LOOKUP_FAILED) elif result.type == result.ROUTE_FAILED: RoutingResult(None, route_params, constants.ROUTING_ROUTE_FAILED) else: return RoutingResult(None, route_params) else: log.error("no Monav routing data - can't route") RoutingResult(None, route_params, constants.ROUTING_NO_DATA)
def get_closest_point_test(self): """Test the get-closest-point functions of the Way class.""" # put some regular points to the way first first = (0.0, 0.0, 0.0) second = (1.0, 0.0, 100.0) third = (2.0, 0.0, 200.0) lle_list = [first, second, third] way = Way(points=lle_list) # add some message points point1 = Point(lat=50.0, lon=0.0, elevation=300.0, message="foo") point2 = Point(lat=75.0, lon=0.0, elevation=600.0, message="bar") way.add_message_point(point1) way.add_message_point(point2) # get closest point result = way.get_closest_point(Point(lat=2.5, lon=0.0)) self.assertEqual(result.getLLE(), third) # get closest message point result = way.get_closest_message_point(Point(lat=76.0, lon=0.0)) self.assertEqual(result, point2)
def radians_test(self): """Test that radians values for Way points are correct.""" # create way with some regular points first = (0.0, 0.0, 0.0) second = (1.0, 1.0, 100.0) lle_list = [first, second] way = Way(points=lle_list) # check the radian output radians_list = [(0.0, 0.0, 0.0), (0.017453292519943295, 0.017453292519943295, 100.0)] self.assertListEqual(way.points_radians_lle, radians_list) self.assertListEqual(way.points_radians_ll, list(map(lambda x: (x[0], x[1]), radians_list))) # add some more points way.add_point(Point(lat=3.0, lon=3.0, elevation=200.0)) way.add_point_lle(5.0, 5.0, 300.0) radians_list.extend([(0.05235987755982989, 0.05235987755982989, 200.0), (0.08726646259971647, 0.08726646259971647, 300.0) ]) # check again self.assertListEqual(way.points_radians_lle, radians_list) self.assertListEqual(way.points_radians_ll, list(map(lambda x: (x[0], x[1]), radians_list)))
def _googleDirections(start, destination, waypoints, params): """ Get driving directions using Google API start and directions can be either point objects or address strings :param start: start of the route :type start: Point object or string :param destination: destination of the route :type destination: Point object or string :param waypoints: points the route should go through :type waypoints: a list of Point objects :param params: requested route parameters :type params: RouteParameters instance """ # check if start and destination are string, # otherwise convert to lat,lon strings from Points if not isinstance(start, six.string_types): start = "%f,%f" % (start.lat, start.lon) if not isinstance(destination, six.string_types): destination = "%f,%f" % (destination.lat, destination.lon) if not waypoints: waypoints = [] flagDir = {'language': params.language} # toll and highway avoidance options if params.avoidHighways and params.avoidTollRoads: flagDir['avoid'] = 'tolls|highways' elif params.avoidHighways: # optionally avoid highways flagDir['avoid'] = 'highways' elif params.avoidTollRoads: # optionally avoid toll roads flagDir['avoid'] = 'tolls' # waypoints waypointOption = None if waypoints: # waypoints are a list of Point objects firstWayPoint = waypoints[0] waypointOption = "%f,%f" % (firstWayPoint.lat, firstWayPoint.lon) for waypoint in waypoints[1:]: waypointOption += "|%f,%f" % (waypoint.lat, waypoint.lon) # respect travel mode routeMode = "driving" # car directions are the default if params.routeMode == constants.ROUTE_BIKE: routeMode = "bicycling " elif params.routeMode == constants.ROUTE_PEDESTRIAN: routeMode = "walking" flagDir['mode'] = routeMode # TODO: check if/how public transport routing works #elif mode == 'train' or mode == 'bus': # directionsType = 'r' #else: # directionsType = "" # the google language code is the second part of this whitespace delimited string #googleLanguageCode = self.get('directionsLanguage', 'en en').split(" ")[1] gMap = _getGmapsInstance() if waypointOption: flagDir['waypoints'] = waypointOption flagDir['sensor'] = 'false' # only import the googlemaps module when actually needed import googlemaps directions = None returnCode = None errorMessage = "" try: directions = gMap.directions(start, destination, flagDir) except googlemaps.GoogleMapsError: import sys e = sys.exc_info()[1] if e.status == 602: log.error("Google routing failed -> address not found") log.error(e) errorMessage = "Address(es) not found" returnCode = constants.ROUTING_ADDRESS_NOT_FOUND elif e.status == 604: log.error("Google routing failed -> no route found") log.error(e) errorMessage = "No route found" returnCode = constants.ROUTING_ROUTE_FAILED elif e.status == 400: log.error("Google routing failed with googlemaps exception," " googlemaps status code:%d", e.status) except Exception: log.exception("onlineServices:GDirections:routing failed with non-googlemaps exception") # convert the directions datastructure returned by Google # to modRana Way object if directions is not None: returnCode = constants.ROUTING_SUCCESS route = Way.from_google_directions_result(directions) else: route = None return route, returnCode, errorMessage
def _googleDirections(start, destination, waypoints, params): """ Get driving directions using Google API start and directions can be either point objects or address strings :param start: start of the route :type start: Point object or string :param destination: destination of the route :type destination: Point object or string :param waypoints: points the route should go through :type waypoints: a list of Point objects :param params: requested route parameters :type params: RouteParameters instance """ # check if start and destination are string, # otherwise convert to lat,lon strings from Points if not isinstance(start, six.string_types): start = "%f,%f" % (start.lat, start.lon) if not isinstance(destination, six.string_types): destination = "%f,%f" % (destination.lat, destination.lon) if not waypoints: waypoints = [] flagDir = {'language': params.language} # toll and highway avoidance options if params.avoidHighways and params.avoidTollRoads: flagDir['avoid'] = 'tolls|highways' elif params.avoidHighways: # optionally avoid highways flagDir['avoid'] = 'highways' elif params.avoidTollRoads: # optionally avoid toll roads flagDir['avoid'] = 'tolls' # waypoints waypointOption = None if waypoints: # waypoints are a list of Point objects firstWayPoint = waypoints[0] waypointOption = "%f,%f" % (firstWayPoint.lat, firstWayPoint.lon) for waypoint in waypoints[1:]: waypointOption += "|%f,%f" % (waypoint.lat, waypoint.lon) # respect travel mode routeMode = "driving" # car directions are the default if params.routeMode == constants.ROUTE_BIKE: routeMode = "bicycling " elif params.routeMode == constants.ROUTE_PEDESTRIAN: routeMode = "walking" flagDir['mode'] = routeMode # TODO: check if/how public transport routing works #elif mode == 'train' or mode == 'bus': # directionsType = 'r' #else: # directionsType = "" # the google language code is the second part of this whitespace delimited string #googleLanguageCode = self.get('directionsLanguage', 'en en').split(" ")[1] gMap = _getGmapsInstance() if waypointOption: flagDir['waypoints'] = waypointOption flagDir['sensor'] = 'false' # only import the googlemaps module when actually needed import googlemaps directions = None returnCode = None errorMessage = "" try: directions = gMap.directions(start, destination, flagDir) except googlemaps.GoogleMapsError: import sys e = sys.exc_info()[1] if e.status == 602: log.error("Google routing failed -> address not found") log.error(e) errorMessage = "Address(es) not found" returnCode = constants.ROUTING_ADDRESS_NOT_FOUND elif e.status == 604: log.error("Google routing failed -> no route found") log.error(e) errorMessage = "No route found" returnCode = constants.ROUTING_ROUTE_FAILED elif e.status == 400: log.error( "Google routing failed with googlemaps exception," " googlemaps status code:%d", e.status) except Exception: log.exception( "onlineServices:GDirections:routing failed with non-googlemaps exception" ) # convert the directions datastructure returned by Google # to modRana Way object if directions is not None: returnCode = constants.ROUTING_SUCCESS route = Way.from_google_directions_result(directions) else: route = None return route, returnCode, errorMessage
def basic_message_points_test(self): """Test using Way with message points.""" # put some regular points to the way first first = (0.0, 0.0, 0.0) second = (1.0, 1.0, 100.0) third = (2.0, 2.0, 200.0) lle_list = [first, second, third] way = Way(points=lle_list) # add some message points point1 = Point(lat=50.0, lon=50.0, elevation=300.0, message="foo") point2 = Point(lat=75.0, lon=75.0, elevation=600.0, message="bar") point3 = Point(lat=100.0, lon=100.0, elevation=1200.0, message="baz") point4 = Point(lat=125.0, lon=125.0, elevation=2400.0, message="abc") point5 = Point(lat=150.0, lon=150.0, elevation=4800.0, message="def") way.add_message_point(point1) way.add_message_point(point2) self.assertEqual(way.message_point_count, 2) self.assertListEqual(way.message_points, [point1, point2]) expected_list1 = [(50.0, 50.0, 300.0), (75.0, 75.0, 600.0)] self.assertListEqual(way.message_points_lle, expected_list1) way.add_message_points([point3, point4, point5]) expected_list2 = expected_list1.copy() expected_list2.extend([(100.0, 100.0, 1200.0), (125.0, 125.0, 2400.0), (150.0, 150.0, 4800.0)]) self.assertEqual(way.message_point_count, 5) self.assertListEqual(way.message_points, [point1, point2, point3, point4, point5]) self.assertListEqual(way.message_points_lle, expected_list2) # check getters self.assertTrue( self._compare_points(way.get_message_point_by_index(2), point3)) self.assertTrue( self._compare_points(way.get_message_point_by_index(-1), point5)) # get message point index # - note that this takes into account the point instance, # so two points with the same content will not be considered the same # - it's a question if this a correct behavior or not :) self.assertEqual(way.get_message_point_index(point1), 0) self.assertEqual(way.get_message_point_index(point3), 2) foo_point = Point(lat=50.0, lon=50.0, elevation=300, message="foo") # foo_point has the same content as point1 but will be considered different self.assertIsNone(way.get_message_point_index(foo_point)) # same thing for stuff that's not points self.assertIsNone(way.get_message_point_index(None)) self.assertIsNone(way.get_message_point_index(1)) self.assertIsNone(way.get_message_point_index(True)) self.assertIsNone(way.get_message_point_index("bar")) self.assertIsNone(way.get_message_point_index([]))
def empty_way_test(self): """Test if an empty Way can be created.""" way = Way() # points self.assertListEqual(way.points_lle, []) self.assertListEqual(way.points_radians_ll, []) self.assertListEqual(way.points_radians_lle, []) self.assertListEqual(way.points_radians_lle, []) self.assertListEqual(way.get_points_lle_radians(drop_elevation=False), []) self.assertListEqual(way.get_points_lle_radians(drop_elevation=True), []) self.assertIsNone(way.get_closest_point(point=Point(lat=0, lon=0))) #message points self.assertListEqual(way.message_points, []) self.assertListEqual(way.message_points_lle, []) self.assertEqual(way.message_point_count, 0) self.assertIsNone( way.get_closest_message_point(point=Point(lat=0, lon=0))) # misc self.assertIsNone(way.length) self.assertIsNone(way.duration) # test getters and setters with self.assertRaises(IndexError): way.get_point_by_index(1) with self.assertRaises(IndexError): way.get_message_point_by_index(1) with self.assertRaises(IndexError): way.set_message_point_by_index(1, Point(lat=1, lon=1)) self.assertIsNone(way.get_closest_message_point(Point(lat=1, lon=1))) # clearing should also work way.clear_message_points()
def set_message_point_test(self): """Test replacing message points already added to a Way.""" way = Way() # add some message points point1 = Point(lat=50.0, lon=50.0, elevation=300.0, message="foo") point2 = Point(lat=75.0, lon=75.0, elevation=600.0, message="bar") point3 = Point(lat=100.0, lon=100.0, elevation=1200.0, message="baz") way.add_message_points([point1, point2, point3]) self.assertEqual(way.get_message_point_by_index(0), point1) self.assertEqual(way.get_message_point_by_index(2), point3) # replace some of the points point11 = Point(lat=51.0, lon=51.0, elevation=301.0, message="foo1") point31 = Point(lat=101.0, lon=101.0, elevation=1201.0, message="baz1") way.set_message_point_by_index(0, point11) way.set_message_point_by_index(2, point31) # check the points have been replaced self.assertEqual(way.get_message_point_by_index(0), point11) self.assertEqual(way.get_message_point_by_index(2), point31) # some sanity checks self.assertEqual(way.message_point_count, 3) self.assertListEqual(way.message_points, [point11, point2, point31]) self.assertListEqual( way.message_points_lle, [point11.getLLE(), point2.getLLE(), point31.getLLE()]) lol_point = Point(lat=50.0, lon=50.0, elevation=300, message="lol") with self.assertRaises(IndexError): way.set_message_point_by_index(3, lol_point) with self.assertRaises(IndexError): way.set_message_point_by_index(-100, lol_point) with self.assertRaises(IndexError): way.set_message_point_by_index(100, lol_point)
def handleMessage(self, message, messageType, args): if message == "clear": self._go_to_initial_state() self.set('startPos', None) self.set('endPos', None) self.set('middlePos', []) # handmade # stop Turn-by-turn navigation, that can be possibly running self.sendMessage('turnByTurn:stop') elif message == 'expectStart': self._expect_start = True elif message == 'setStart': if self._select_one_point: self.set('endPos', None) proj = self.m.get('projection', None) if proj and self._expect_start: lastClick = self.get('lastClickXY', None) (x, y) = lastClick # x and y must be floats, otherwise strange rounding errors # occur when converting to lat lon coordinates (lat, lon) = proj.xy2ll(x, y) self.set('startPos', (lat, lon)) self._start = Waypoint(lat, lon) self._destination = None # clear destination self._expect_start = False elif message == 'expectMiddle': # handmade self._expect_middle = True # handmade elif message == 'setMiddle': # handmade proj = self.m.get('projection', None) if proj and self._expect_middle: lastClick = self.get('lastClickXY', None) (x, y) = lastClick # x and y must be floats, otherwise strange rounding errors # occur when converting to lat lon coordinates (lat, lon) = proj.xy2ll(x, y) middle_pos = self.get('middlePos', []) middle_pos.append((lat, lon, None, "")) self.set('middlePos', middle_pos) # if in handmade input mode, # also ask for instructions for the given point if self._handmade: self.sendMessage('route:middleInput') self._expect_middle = False elif message == 'expectEnd': self._expect_end = True elif message == 'setEnd': if self._select_one_point: self.set('startPos', None) proj = self.m.get('projection', None) if proj and self._expect_end: lastClick = self.get('lastClickXY', None) (x, y) = lastClick # x and y must be floats, otherwise strange rounding errors # occur when converting to lat lon coordinates (lat, lon) = proj.xy2ll(x, y) self.set('endPos', (lat, lon)) self._destination = Waypoint(lat, lon) self._start = None # clear start self._expect_end = False elif message == "handmade": self.set('startPos', None) self.set('middlePos', []) self.set('endPos', None) self._select_one_point = False self._select_two_points = True self._select_many_points = True self._handmade = True self._osd_menu_state = OSD_EDIT self.log.info("Using handmade routing") self.log.info(self._handmade) elif message == "selectTwoPoints": self.set('startPos', None) self.set('endPos', None) self.set('middlePos', []) self._select_one_point = False self._select_two_points = True self._select_many_points = False self._osd_menu_state = OSD_EDIT elif message == "selectOnePoint": self.set('startPos', None) self.set('endPos', None) self.set('middlePos', []) self._select_two_points = True # we reuse the p2p menu self._select_one_point = True self._select_many_points = False self._osd_menu_state = OSD_EDIT elif message == "p2pRoute": # simple route, between two points destination = self.get("endPos", None) start = self.get("startPos", None) if destination and start: middle_points = self.get('middlePos', []) self.llRoute(start, destination, middle_points) elif message == "p2phmRoute": # simple route, from start to middle to end (handmade routing) start = self.get("startPos", None) destination = self.get("endPos", None) if start and destination: toLat, toLon = destination fromLat, fromLon = start middle_points = self.get("middlePos", []) self.log.info("Handmade route") self.log.info("%f,%f", fromLat, fromLon) self.log.info("through") self.log.info(middle_points) self.log.info("to %f,%f", toLat, toLon) handmade_route = Way.from_handmade(start, middle_points, destination) self._handle_routing_result_cb((handmade_route, "", 0)) elif message == "p2posRoute": # simple route, from here to selected point start_pos = self.get('startPos', None) end_pos = self.get('endPos', None) pos = self.get('pos', None) start = None destination = None if pos is None: # well, we don't know where we are, so we don't know here to go :) return None if start_pos is None and end_pos is None: # we know where we are, but we don't know where we should go :) return None if start_pos is not None: # we want a route from somewhere to our current position start = start_pos destination = pos if end_pos is not None: # we go from here to somewhere start = pos destination = end_pos middle_points = self.get("middlePos", []) if start and destination: self.llRoute(start, destination, middle_points) elif message == "route": # find a route if messageType == 'md': # message-list based unpack requires a string argument of length 4 routing if args: messageType = args['type'] start = None destination = None if messageType == 'll2ll': start = (float(args['fromLat']), float(args['fromLon'])) destination = (float(args['toLat']), float(args['toLon'])) elif messageType == 'pos2ll': pos = self.get('pos', None) if pos: start = pos destination = (float(args['toLat']), float(args['toLon'])) if start and destination: # are we GO for routing ? try: self.llRoute(start, destination) except Exception: self.sendMessage( 'ml:notification:m:No route found;3') self.log.exception("exception during routing") if "show" in args: # switch to map view and go to start/destination, if requested where = args['show'] if where == 'start': self.sendMessage( 'mapView:recentre %f %f|set:menu:None' % start) elif where == "destination": self.sendMessage( 'mapView:recentre %f %f|set:menu:None' % destination) else: # simple route, from here to selected point # disable the point selection GUIs self._select_many_points = False # handmade self._select_two_points = False self._select_one_point = False self._osd_menu_state = OSD_CURRENT_ROUTE start = self.get("pos", None) destination = self.get("selectedPos", None) destination = [float(a) for a in destination.split(",")] if start and destination: self.llRoute(start, destination) elif message == 'store_route': load_tracklogs = self.m.get('loadTracklogs', None) if load_tracklogs is None: self.log.error( "can't store route without the load_tracklog module") return if not self._directions: self.log.info("the route is empty, so it will not be stored") return # TODO: rewrite this when we support more routing providers load_tracklogs.store_route_and_set_active( self._directions.points_lle, '', 'online') elif message == "clearRoute": self._go_to_initial_state() elif message == 'startInput': entry = self.m.get('textEntry', None) if entry is None: self.log.error("text entry module not available") return entryText = self.get('startAddress', "") entry.entryBox(self, 'start', 'Input the start address', entryText) elif message == 'middleInput': # handmade entry = self.m.get('textEntry', None) if entry is None: return entryText = "" entry.entryBox(self, 'middle', 'Input the directions for this middle point', entryText) elif message == 'destinationInput': entry = self.m.get('textEntry', None) if entry is None: self.log.error("text entry module not available") return entryText = self.get('destinationAddress', "") entry.entryBox(self, 'destination', 'Input the destination address', entryText) elif message == 'addressRoute': start_address = self.get('startAddress', None) destination_address = self.get('destinationAddress', None) if start_address and destination_address: self.log.info("address routing") self.set('menu', None) # go to the map screen self.addressRoute(start_address, destination_address) else: # notify the user about insufficient input and remain in the menu self.log.error( "can't route - start or destination (or both) not set") if start_address is None and destination_address is None: self.notify("Can't route: start & destination not set", 3000) elif start_address is None: self.notify("Can't route: start not set", 3000) elif destination_address is None: self.notify("Can't route: destination not set", 3000) elif message == 'posToStart': pos = self.get('pos', None) if pos: posString = "%f,%f" % pos self._start_address = posString # set as current address self.set('startAddress', posString) # also store in the persistent dictionary elif message == 'posToDestination': pos = self.get('pos', None) if pos: posString = "%f,%f" % pos self._destination_address = posString # set as current address self.set('destinationAddress', posString) # also store in the persistent dictionary elif messageType == 'ms' and message == 'addressRouteMenu': if args == 'swap': # get current values start = self.get('startAddress', None) destination = self.get('destinationAddress', None) # swap them self.set('startAddress', destination) self.set('destinationAddress', start) # redraw the screen to show the change elif messageType == "ms" and message == "setOSDState": self._osd_menu_state = int(args)
def _rescueLogs(self): """rescue any log files that were not exported to GPX previously""" # get log folder path logFolder = self.getLogFolderPath() # check out the log folder for temporary files # first scan for primary logs primaryLogs = glob.glob("%s/*.temporary_csv_1" % logFolder) secondaryLogs = glob.glob("%s/*.temporary_csv_2" % logFolder) if primaryLogs or secondaryLogs: self.log.info("unsaved temporary tracklogs detected") self.notify("exporting temporary tracklogs to GPX", 5000) if primaryLogs: self.log.info( 'exporting %d unsaved primary tracklog files to GPX', len(primaryLogs)) for logPath in primaryLogs: # export any found files self.log.info('exporting %s to GPX', logPath) try: w1 = Way.from_csv(logPath, delimiter=",") exportPath = "%s.gpx" % os.path.splitext(logPath)[0] # does the GPX file already exist ? # TODO: check if the GPX file is corrupted and swap with newly exported one ? # (eq. caused by a crash during saving the GPX file) if os.path.exists(exportPath): # save to backup path exportPath = "%s_1.gpx" % os.path.splitext( logPath)[0] w1.save_to_GPX(exportPath) self.log.info( 'GPX export of unsaved primary tracklog successful' ) # success, delete temporary files # primary os.remove(logPath) self.log.debug('primary temporary file %s deleted', logPath) # secondary secondaryPath = "%s.temporary_csv_2" % os.path.splitext( logPath)[0] if os.path.exists(secondaryPath): os.remove(secondaryPath) self.log.debug( 'secondary temporary file %s deleted', secondaryPath) except Exception: self.log.exception( 'exporting unsaved primary log file failed') failedPath = "%s_1.csv" % os.path.splitext(logPath)[0] self.log.info('renaming to %s instead', failedPath) try: shutil.move(logPath, failedPath) self.log.info("renaming successful") except Exception: self.log.exception('renaming %s to %s failed', logPath, failedPath) # rescan for secondary logs # (there should be only secondary logs that # either don't have primary logs or where primary logs # failed to parse (primary logs delete secondary logs # after successful processing) secondaryLogs = glob.glob("%s/*.temporary_csv_2" % logFolder) if secondaryLogs: self.log.info( 'exporting %d unsaved secondary log files to GPX' % len(primaryLogs)) for logPath in secondaryLogs: # export any found files self.log.info('exporting %s to GPX' % logPath) try: w2 = Way.from_csv(logPath, delimiter=",") exportPath = "%s.gpx" % os.path.splitext(logPath)[0] # does the GPX file already exist ? # TODO: check if the GPX file is corrupted and swap with newly exported one ? # (eq. caused by a crash during saving the GPX file) if os.path.exists(exportPath): # save to backup path exportPath = "%s_2.gpx" % os.path.splitext( logPath)[0] w2.save_to_GPX(exportPath) self.log.info( 'GPX export of unsaved secondary tracklog successful' ) # success, delete temporary file # secondary # (primary is either not there or was already removed in primary pass) os.remove(logPath) self.log.info('secondary temporary file %s deleted' % logPath) except Exception: self.log.exception( 'exporting unsaved secondary log file failed') failedPath = "%s_2.csv" % os.path.splitext(logPath)[0] self.log.info('renaming to %s instead', failedPath) try: shutil.move(logPath, failedPath) self.log.info("renaming successful") except Exception: self.log.exception('renaming %s to %s failed', logPath, failedPath) self.log.debug("unsaved tracklog handling finished")
def _rescueLogs(self): """rescue any log files that were not exported to GPX previously""" # get log folder path logFolder = self.getLogFolderPath() # check out the log folder for temporary files # first scan for primary logs primaryLogs = glob.glob("%s/*.temporary_csv_1" % logFolder) secondaryLogs = glob.glob("%s/*.temporary_csv_2" % logFolder) if primaryLogs or secondaryLogs: self.log.info("unsaved temporary tracklogs detected") self.notify("exporting temporary tracklogs to GPX", 5000) self.set('needRedraw', True) if primaryLogs: self.log.info('exporting %d unsaved primary tracklog files to GPX', len(primaryLogs)) for logPath in primaryLogs: # export any found files self.log.info('exporting %s to GPX', logPath) try: w1 = Way.from_csv(logPath, delimiter=",") exportPath = "%s.gpx" % os.path.splitext(logPath)[0] # does the GPX file already exist ? # TODO: check if the GPX file is corrupted and swap with newly exported one ? # (eq. caused by a crash during saving the GPX file) if os.path.exists(exportPath): # save to backup path exportPath = "%s_1.gpx" % os.path.splitext(logPath)[0] w1.saveToGPX(exportPath) self.log.info('GPX export of unsaved primary tracklog successful') # success, delete temporary files # primary os.remove(logPath) self.log.debug('primary temporary file %s deleted', logPath) # secondary secondaryPath = "%s.temporary_csv_2" % os.path.splitext(logPath)[0] if os.path.exists(secondaryPath): os.remove(secondaryPath) self.log.debug('secondary temporary file %s deleted', secondaryPath) except Exception: self.log.exception('exporting unsaved primary log file failed') failedPath = "%s_1.csv" % os.path.splitext(logPath)[0] self.log.info('renaming to %s instead', failedPath) try: shutil.move(logPath, failedPath) self.log.info("renaming successful") except Exception: self.log.exception('renaming %s to %s failed', logPath, failedPath) # rescan for secondary logs # (there should be only secondary logs that # either don't have primary logs or where primary logs # failed to parse (primary logs delete secondary logs # after successful processing) secondaryLogs = glob.glob("%s/*.temporary_csv_2" % logFolder) if secondaryLogs: self.log.info('exporting %d unsaved secondary log files to GPX' % len(primaryLogs)) for logPath in secondaryLogs: # export any found files self.log.info('exporting %s to GPX' % logPath) try: w2 = Way.from_csv(logPath, delimiter=",") exportPath = "%s.gpx" % os.path.splitext(logPath)[0] # does the GPX file already exist ? # TODO: check if the GPX file is corrupted and swap with newly exported one ? # (eq. caused by a crash during saving the GPX file) if os.path.exists(exportPath): # save to backup path exportPath = "%s_2.gpx" % os.path.splitext(logPath)[0] w2.saveToGPX(exportPath) self.log.info('GPX export of unsaved secondary tracklog successful') # success, delete temporary file # secondary # (primary is either not there or was already removed in primary pass) os.remove(logPath) self.log.info('secondary temporary file %s deleted' % logPath) except Exception: self.log.exception('exporting unsaved secondary log file failed') failedPath = "%s_2.csv" % os.path.splitext(logPath)[0] self.log.info('renaming to %s instead', failedPath) try: shutil.move(logPath, failedPath) self.log.info("renaming successful") except Exception: self.log.exception('renaming %s to %s failed', logPath, failedPath) self.log.debug("unsaved tracklog handling finished")