예제 #1
0
 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)
예제 #2
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, [])
예제 #3
0
    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")
예제 #4
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, 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)
예제 #5
0
 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))
예제 #6
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)
예제 #7
0
 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)
예제 #8
0
 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)))
예제 #9
0
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
예제 #10
0
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
예제 #11
0
 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([]))
예제 #12
0
    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()
예제 #13
0
    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)
예제 #14
0
    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)
예제 #15
0
    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")
예제 #16
0
    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")