Exemplo n.º 1
0
    def get_street_network_routing_matrix(self, origins, destinations, mode,
                                          max_duration, request, **kwargs):
        speed_switcher = {
            "walking": request['walking_speed'],
            "bike": request['bike_speed'],
            "car": request['car_speed'],
            "bss": request['bss_speed'],
        }
        req = request_pb2.Request()
        req.requested_api = type_pb2.street_network_routing_matrix

        for o in origins:
            orig = req.sn_routing_matrix.origins.add()
            orig.place = 'coord:{c.lon}:{c.lat}'.format(
                c=get_pt_object_coord(o))
            orig.access_duration = 0
        for d in destinations:
            dest = req.sn_routing_matrix.destinations.add()
            dest.place = 'coord:{c.lon}:{c.lat}'.format(
                c=get_pt_object_coord(d))
            dest.access_duration = 0

        req.sn_routing_matrix.mode = mode
        req.sn_routing_matrix.speed = speed_switcher.get(
            mode, kwargs.get("walking"))
        req.sn_routing_matrix.max_duration = max_duration

        res = self._call_asgard(req)
        # TODO handle car park
        if res.HasField('error'):
            logging.getLogger(__name__).error(
                'routing matrix query error {}'.format(res.error))
            raise TechnicalError('routing matrix fail')
        return res.sn_routing_matrix
Exemplo n.º 2
0
def _create_crowfly(pt_journey, crowfly_origin, crowfly_destination, begin, end, mode):
    section = response_pb2.Section()
    section.type = response_pb2.CROW_FLY
    section.origin.CopyFrom(crowfly_origin)
    section.destination.CopyFrom(crowfly_destination)
    section.duration = end - begin
    pt_journey.durations.total += section.duration
    pt_journey.duration += section.duration
    section.begin_date_time = begin
    section.end_date_time = end
    if section.duration > 0:
        section.street_network.mode = MODE_TO_PB_MODE.get(mode)
    # mode is always walking for a teleportation crow_fly
    else:
        section.street_network.mode = response_pb2.Walking

    # Calculate section length
    from_coord = get_pt_object_coord(section.origin)
    to_coord = get_pt_object_coord(section.destination)
    section.length = int(crowfly_distance_between(from_coord, to_coord))

    # The section "distances" and "durations" in the response needs to be updated according to the mode.
    # only if it isn't a 'free' crow_fly
    if section.duration > 0:
        setattr(pt_journey.distances, mode, (getattr(pt_journey.distances, mode) + section.length))
        setattr(pt_journey.durations, mode, (getattr(pt_journey.durations, mode) + section.duration))

    section.id = six.text_type(generate_id())
    return section
Exemplo n.º 3
0
    def get_street_network_routing_matrix(self, origins, destinations, mode, max_duration, request, **kwargs):
        if len(origins) > 1:
            if len(destinations) > 1:
                logging.getLogger(__name__).error('routing matrix error, no unique center point')
                raise TechnicalError('routing matrix error, no unique center point')

        req = request_pb2.Request()
        req.requested_api = type_pb2.street_network_routing_matrix

        for o in origins:
            orig = req.sn_routing_matrix.origins.add()
            orig.place = 'coord:{c.lon}:{c.lat}'.format(c=get_pt_object_coord(o))
            orig.access_duration = 0
        for d in destinations:
            dest = req.sn_routing_matrix.destinations.add()
            dest.place = 'coord:{c.lon}:{c.lat}'.format(c=get_pt_object_coord(d))
            dest.access_duration = 0

        req.sn_routing_matrix.max_duration = max_duration
        req.sn_routing_matrix.mode = mode

        res = self._call_asgard(req)
        #TODO handle car park
        if res.HasField('error'):
            logging.getLogger(__name__).error('routing matrix query error {}'.format(res.error))
            raise TechnicalError('routing matrix fail')
        return res.sn_routing_matrix
Exemplo n.º 4
0
    def _add_first_and_last_coord(self, dp):
        if not dp or not dp.journeys or not dp.journeys[0].sections:
            return

        nb_coords = sum((len(sec.street_network.coordinates)
                         for sec in dp.journeys[0].sections))
        if nb_coords < 2:
            return

        starting_coords = dp.journeys[0].sections[0].street_network.coordinates
        # we are inserting the coord of the origin at the beginning of the geojson
        coord = utils.get_pt_object_coord(self._orig_obj)
        if starting_coords and coord != starting_coords[0]:
            starting_coords.add(lon=coord.lon, lat=coord.lat)
            # we cannot insert an element at the beginning of a list :(
            # a little algo to move the last element to the beginning
            tmp = type_pb2.GeographicalCoord()
            for i in range(len(starting_coords)):
                tmp.CopyFrom(starting_coords[i])
                starting_coords[i].CopyFrom(starting_coords[-1])
                starting_coords[-1].CopyFrom(tmp)

        ending_coords = dp.journeys[0].sections[-1].street_network.coordinates
        # we are appending the coord of the destination at the end of the geojson
        coord = utils.get_pt_object_coord(self._dest_obj)
        if ending_coords and coord != ending_coords[-1]:
            ending_coords.add(lon=coord.lon, lat=coord.lat)
Exemplo n.º 5
0
    def _direct_path(
        self,
        instance,
        mode,
        pt_object_origin,
        pt_object_destination,
        fallback_extremity,
        request,
        direct_path_type,
        request_id,
    ):
        # if the crowfly distance between origin and destination is too large, there is no need to call asgard
        crowfly_distance = crowfly_distance_between(
            get_pt_object_coord(pt_object_origin),
            get_pt_object_coord(pt_object_destination))

        # if the crowfly distance between origin and destination is
        # bigger than max_{mode}_direct_path_distance don't compute direct_path
        if crowfly_distance > int(
                request['max_{mode}_direct_path_distance'.format(mode=mode)]):
            return response_pb2.Response()

        if (crowfly_distance / float(request['{mode}_speed'.format(mode=mode)])
                >
                request['max_{mode}_direct_path_duration'.format(mode=mode)]):
            return response_pb2.Response()

        language = self.get_language_parameter(request)

        req = self._create_direct_path_request(
            mode,
            pt_object_origin,
            pt_object_destination,
            fallback_extremity,
            request,
            direct_path_type,
            language,
        )

        response = self._call_asgard(req)

        # car_no_park is interpreted as car for Asgard, we need to overwrite the streetnetwork mode here
        if mode == "car_no_park":
            try:
                response.journeys[0].sections[
                    0].street_network.mode = response_pb2.CarNoPark
            except AttributeError:
                pass
            except Exception as e:
                raise e

        if response and mode in (FallbackModes.bike.name,
                                 FallbackModes.bss.name):
            response = self._add_cycle_lane_length(response)

        return response
Exemplo n.º 6
0
 def _make_request_arguments_direct_path(cls, origin, destination, bike_speed_mps=3.33):
     coord_orig = get_pt_object_coord(origin)
     coord_dest = get_pt_object_coord(destination)
     return {
         'waypoints': [
             {'latitude': coord_orig.lat, 'longitude': coord_orig.lon},
             {'latitude': coord_dest.lat, 'longitude': coord_dest.lon},
         ],
         'transportModes': ['BIKE'],
         'bikeDetails': cls._make_request_arguments_bike_details(bike_speed_mps),
     }
Exemplo n.º 7
0
 def _make_request_arguments_direct_path(cls, origin, destination):
     coord_orig = get_pt_object_coord(origin)
     coord_dest = get_pt_object_coord(destination)
     return {
         'waypoints': [
             {'latitude': coord_orig.lat, 'longitude': coord_orig.lon},
             {'latitude': coord_dest.lat, 'longitude': coord_dest.lon}
         ],
         'bikeDetails': {
             'profile': 'MEDIAN', # can be BEGINNER, EXPERT
             'bikeType': 'TRADITIONAL', # can be 'BSS'
             # 'averageSpeed': '6' # in km/h, BEGINNER sets it to 13
         },
         'transportModes': ['BIKE']
     }
Exemplo n.º 8
0
    def _do_request(self):
        logger = logging.getLogger(__name__)
        logger.debug("requesting proximities by crowfly from %s in %s",
                     self._requested_place_obj.uri, self._mode)

        # When max_duration_to_pt is 0, there is no need to compute the fallback to pt, except if place is a stop_point
        # or a stop_area
        if self._max_duration == 0:
            logger.debug(
                "max duration equals to 0, no need to compute proximities by crowfly"
            )

            # When max_duration_to_pt is 0, we can get on the public transport ONLY if the place is a stop_point
            if self._instance.georef.get_stop_points_from_uri(
                    self._requested_place_obj.uri):
                return [self._requested_place_obj]

        coord = utils.get_pt_object_coord(self._requested_place_obj)
        if coord.lat and coord.lon:
            crow_fly = self._get_crow_fly(self._instance.georef)

            logger.debug("finish proximities by crowfly from %s in %s",
                         self._requested_place_obj.uri, self._mode)
            return crow_fly

        logger.debug("the coord of requested places is not valid: %s", coord)
        return []
Exemplo n.º 9
0
    def _do_request(self):
        logger = logging.getLogger(__name__)
        logger.debug("requesting places with free access from %s",
                     self._requested_place_obj.uri)

        stop_points = []
        place = self._requested_place_obj

        if place.embedded_type == type_pb2.STOP_AREA:
            stop_points = self._get_stop_points_for_stop_area(
                self._instance.georef, place.uri)
        elif place.embedded_type == type_pb2.ADMINISTRATIVE_REGION:
            stop_points = [
                sp for sa in place.administrative_region.main_stop_areas
                for sp in sa.stop_points
            ]
        elif place.embedded_type == type_pb2.STOP_POINT:
            stop_points = [place.stop_point]

        crowfly = {stop_point.uri for stop_point in stop_points}

        coord = utils.get_pt_object_coord(place)
        odt = set()

        if coord:
            odt_sps = self._get_odt_stop_points(self._instance.georef, coord)
            [odt.add(stop_point.uri) for stop_point in odt_sps]

        logger.debug("finish places with free access from %s",
                     self._requested_place_obj.uri)

        # free_radius is empty until the proximities by crowfly are available
        free_radius = set()

        return PlaceFreeAccessResult(crowfly, odt, free_radius)
Exemplo n.º 10
0
    def _format_coord(cls, pt_object, api='route'):
        if api not in ['route', 'sources_to_targets']:
            logging.getLogger(__name__).error('Valhalla routing service , invalid api {}'.format(api))
            raise ApiNotFound('Valhalla routing service , invalid api {}'.format(api))

        coord = get_pt_object_coord(pt_object)
        dict_coord = {"lat": coord.lat, "lon": coord.lon}
        if api == 'route':
            dict_coord["type"] = "break"
        return dict_coord
Exemplo n.º 11
0
 def _get_coord(self, pt_object):
     if not isinstance(pt_object, type_pb2.PtObject):
         logging.getLogger(__name__).error('Invalid pt_object')
         raise InvalidArguments('Invalid pt_object')
     coord = get_pt_object_coord(pt_object)
     if not coord:
         logging.getLogger(__name__).error(
             'Invalid coord for ptobject type: {}'.format(
                 pt_object.embedded_type))
         raise UnableToParse('Invalid coord for ptobject type: {}'.format(
             pt_object.embedded_type))
     return coord
Exemplo n.º 12
0
    def to_value(self, value):
        if not hasattr(value, 'type'):
            return None

        coords = []

        try:
            if value.type == response_pb2.STREET_NETWORK:
                coords = value.street_network.coordinates
            elif value.type == response_pb2.CROW_FLY:
                if len(value.shape) != 0:
                    coords = value.shape
                else:
                    coords.append(get_pt_object_coord(value.origin))
                    coords.append(get_pt_object_coord(value.destination))
            elif value.type == response_pb2.RIDESHARING and len(value.shape) != 0:
                coords = value.shape
            elif value.type == response_pb2.PUBLIC_TRANSPORT:
                coords = value.shape
            elif value.type == response_pb2.TRANSFER:
                if value.street_network and value.street_network.coordinates:
                    coords = value.street_network.coordinates
                else:
                    coords.append(value.origin.stop_point.coord)
                    coords.append(value.destination.stop_point.coord)
            else:
                return
        except UnableToParse:
            return
        except InvalidArguments:
            return

        response = {
            "type": "LineString",
            "coordinates": [],
            "properties": [{"length": 0 if not value.HasField(str("length")) else value.length}],
        }
        for coord in coords:
            response["coordinates"].append([coord.lon, coord.lat])
        return response
Exemplo n.º 13
0
def _create_crowfly(pt_journey, crowfly_origin, crowfly_destination, begin, end, mode):
    section = response_pb2.Section()
    section.type = response_pb2.CROW_FLY
    section.origin.CopyFrom(crowfly_origin)
    section.destination.CopyFrom(crowfly_destination)
    section.duration = end - begin
    pt_journey.durations.total += section.duration
    pt_journey.duration += section.duration
    section.begin_date_time = begin
    section.end_date_time = end
    if section.duration > 0:
        section.street_network.mode = FallbackModes[mode].value
    # mode is always walking for a teleportation crow_fly
    else:
        section.street_network.mode = response_pb2.Walking

    # Calculate section length
    from_coord = get_pt_object_coord(section.origin)
    to_coord = get_pt_object_coord(section.destination)
    section.length = int(crowfly_distance_between(from_coord, to_coord))

    section.id = six.text_type(generate_id())
    return section
Exemplo n.º 14
0
def _get_places_crowfly(instance, mode, place, max_duration_to_pt, max_nb_crowfly=5000, **kwargs):
    # When max_duration_to_pt is 0, there is no need to compute the fallback to pt, except if place is a stop_point or a
    # stop_area
    if max_duration_to_pt == 0:
        # When max_duration_to_pt is 0, we can get on the public transport ONLY if the place is a stop_point
        if instance.georef.get_stop_points_from_uri(place.uri):
            return {mode: place}
        else:
            return {mode: []}
    coord = get_pt_object_coord(place)
    if not coord.lat and not coord.lon:
        return {mode: []}
    res = instance.georef.get_crow_fly(get_uri_pt_object(place), mode, max_duration_to_pt,
                                       max_nb_crowfly, **kwargs)

    return {mode: res}
Exemplo n.º 15
0
    def add_parking_section_in_direct_path(self, response, pt_object,
                                           direct_path_type):
        logger = logging.getLogger(__name__)
        logger.info("Creating parking section for direct path")

        for journey in response.journeys:
            parking_duration = self.parking_module.get_parking_duration(
                get_pt_object_coord(pt_object))

            parking_section = response_pb2.Section()

            parking_section.id = 'section_1'
            parking_section.origin.CopyFrom(pt_object)
            parking_section.destination.CopyFrom(pt_object)
            parking_section.duration += parking_duration

            journey.duration += parking_duration
            journey.durations.total += parking_duration

            if direct_path_type == StreetNetworkPathType.ENDING_FALLBACK:
                # And we have to complete the destination of the first section ourselves
                # Because Jormun does not do it afterwards
                journey.sections[0].origin.CopyFrom(pt_object)
                parking_section.type = response_pb2.LEAVE_PARKING
                parking_section.begin_date_time = journey.sections[
                    0].begin_date_time
                parking_section.end_date_time = parking_section.begin_date_time + parking_duration
                # we push off the whole car section
                for s in journey.sections:
                    s.begin_date_time += parking_duration
                    s.end_date_time += parking_duration
            else:
                # And we have to complete the destination of the first section ourselves
                # Because Jormun does not do it afterwards
                journey.sections[-1].destination.CopyFrom(pt_object)
                parking_section.type = response_pb2.PARK
                parking_section.begin_date_time = journey.sections[
                    -1].end_date_time
                parking_section.end_date_time = parking_section.begin_date_time + parking_duration

            journey.arrival_date_time += parking_duration

            journey.sections.extend([parking_section])
            journey.nb_sections += 1
Exemplo n.º 16
0
def _update_crowfly_duration(instance, mode, requested_entry_point):
    """
    compute the list of stoppoint that can be accessed for free by crowfly
    for a stoparea it's the list of it's stoppoints
    for an admin it's the list of it's main_stop_area's stoppoints

    we also look if there are on demand transport (odt) stoppoints in the area

    :return
        the list of the freely accessed stoppoints
        the list of odt stoppoints
        the fallback duration for all those stoppoints
    """
    stop_points = []
    if requested_entry_point.embedded_type == type_pb2.STOP_AREA:
        stop_points = instance.georef.get_stop_points_for_stop_area(
            requested_entry_point.uri)
    elif requested_entry_point.embedded_type == type_pb2.ADMINISTRATIVE_REGION:
        stop_points = [
            sp for sa in
            requested_entry_point.administrative_region.main_stop_areas
            for sp in sa.stop_points
        ]
    elif requested_entry_point.embedded_type == type_pb2.STOP_POINT:
        stop_points = [requested_entry_point.stop_point]

    crowfly_sps = set()
    odt_stop_points = set()
    fallback_list = collections.defaultdict(dict)
    for stop_point in stop_points:
        fallback_list[mode][stop_point.uri] = 0
        crowfly_sps.add(stop_point.uri)

    coord = get_pt_object_coord(requested_entry_point)

    if coord:
        odt_sps = instance.georef.get_odt_stop_points(coord)
        for stop_point in odt_sps:
            fallback_list[mode][stop_point.uri] = 0
            odt_stop_points.add(stop_point.uri)

    return crowfly_sps, odt_stop_points, fallback_list
Exemplo n.º 17
0
 def get_uri_pt_object(self, pt_object):
     return 'coord:{c.lon}:{c.lat}'.format(c=get_pt_object_coord(pt_object))
Exemplo n.º 18
0
def _get_coord_for_matrix(pt_object):
    coord = get_pt_object_coord(pt_object)
    return {"lat": coord.lat, "lng": coord.lon}
Exemplo n.º 19
0
 def _pt_object_summary_isochrone(cls, pt_object):
     coord = get_pt_object_coord(pt_object)
     return [coord.lat, coord.lon, None]
Exemplo n.º 20
0
 def _pt_object_summary_isochrone(cls, pt_object):
     coord = get_pt_object_coord(pt_object)
     return [coord.lat, coord.lon, getattr(pt_object, 'uri', None)]
Exemplo n.º 21
0
    def _compute_journeys(self, future_manager, request, instance,
                          krakens_call, context, request_type):
        """
        For all krakens_call, call the kraken and aggregate the responses

        Note: the responses will only attach a crowfly section as a fallback. Street network will be
        done when calling finalise_journeys

        return the list of all responses
        """

        logger = logging.getLogger(__name__)
        logger.debug('request datetime: %s', request['datetime'])
        request_id = request["request_id"]
        logger.debug("request_id : {}".format(request_id))

        requested_dep_modes_with_pt = {
            mode
            for mode, _, direct_path_type in krakens_call
            if direct_path_type != "only"
        }
        requested_arr_modes_with_pt = {
            mode
            for _, mode, direct_path_type in krakens_call
            if direct_path_type != "only"
        }

        # These are the modes in first_section_modes[] and direct_path_modes[]
        # We need to compute direct_paths for them either because we requested it with direct_path_modes[]
        # Or because we need them to optimize the pt_journey computation
        requested_direct_path_modes = {
            mode
            for mode, _, direct_path_type in krakens_call
            if direct_path_type == "only"
        }
        requested_direct_path_modes.update(requested_dep_modes_with_pt)

        if context.partial_response_is_empty:
            logger.debug('requesting places by uri orig: %s dest %s',
                         request['origin'], request['destination'])

            context.requested_orig = PlaceByUri(
                future_manager=future_manager,
                instance=instance,
                uri=request['origin'],
                request_id="{}_place_origin".format(request_id),
            )
            context.requested_dest = PlaceByUri(
                future_manager=future_manager,
                instance=instance,
                uri=request['destination'],
                request_id="{}_place_dest".format(request_id),
            )

            context.requested_orig_obj = get_entry_point_or_raise(
                context.requested_orig, request['origin'])
            context.requested_dest_obj = get_entry_point_or_raise(
                context.requested_dest, request['destination'])

            context.streetnetwork_path_pool = StreetNetworkPathPool(
                future_manager=future_manager, instance=instance)

            period_extremity = PeriodExtremity(request['datetime'],
                                               request['clockwise'])

            for mode in requested_direct_path_modes:
                context.streetnetwork_path_pool.add_async_request(
                    requested_orig_obj=context.requested_orig_obj,
                    requested_dest_obj=context.requested_dest_obj,
                    mode=mode,
                    period_extremity=period_extremity,
                    request=request,
                    streetnetwork_path_type=StreetNetworkPathType.DIRECT,
                    request_id="{}_direct_path_mode_{}".format(
                        request_id, mode),
                )

            # if max_duration(time to pass in pt) is zero, there is no need to continue,
            # we return all direct path without pt
            if request['max_duration'] == 0:
                res = [
                    context.streetnetwork_path_pool.wait_and_get(
                        requested_orig_obj=context.requested_orig_obj,
                        requested_dest_obj=context.requested_dest_obj,
                        mode=mode,
                        request=request,
                        period_extremity=period_extremity,
                        streetnetwork_path_type=StreetNetworkPathType.DIRECT,
                    ) for mode in requested_direct_path_modes
                ]
                # add SN feed publishers
                context.streetnetwork_path_pool.add_feed_publishers(
                    request, requested_direct_path_modes, res)
                return res

            # We'd like to get the duration of a direct path to do some optimizations in ProximitiesByCrowflyPool and
            # FallbackDurationsPool.
            # Note :direct_paths_by_mode is a dict of mode vs future of a direct paths, this line is not blocking
            context.direct_paths_by_mode = context.streetnetwork_path_pool.get_all_direct_paths(
            )

            crowfly_distance = crowfly_distance_between(
                get_pt_object_coord(context.requested_orig_obj),
                get_pt_object_coord(context.requested_dest_obj))
            context.orig_proximities_by_crowfly = ProximitiesByCrowflyPool(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_orig_obj,
                modes=requested_dep_modes_with_pt,
                request=request,
                direct_paths_by_mode=context.direct_paths_by_mode,
                max_nb_crowfly_by_mode=request['max_nb_crowfly_by_mode'],
                request_id="{}_crowfly_orig".format(request_id),
                o_d_crowfly_distance=crowfly_distance,
            )

            context.dest_proximities_by_crowfly = ProximitiesByCrowflyPool(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_dest_obj,
                modes=requested_arr_modes_with_pt,
                request=request,
                direct_paths_by_mode=context.direct_paths_by_mode,
                max_nb_crowfly_by_mode=request['max_nb_crowfly_by_mode'],
                request_id="{}_crowfly_dest".format(request_id),
                o_d_crowfly_distance=crowfly_distance,
            )

            context.orig_places_free_access = PlacesFreeAccess(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_orig_obj,
                request_id="{}_places_free_access_orig".format(request_id),
            )
            context.dest_places_free_access = PlacesFreeAccess(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_dest_obj,
                request_id="{}_places_free_access_dest".format(request_id),
            )

            context.orig_fallback_durations_pool = FallbackDurationsPool(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_orig_obj,
                modes=requested_dep_modes_with_pt,
                proximities_by_crowfly_pool=context.
                orig_proximities_by_crowfly,
                places_free_access=context.orig_places_free_access,
                direct_paths_by_mode=context.direct_paths_by_mode,
                request=request,
                direct_path_type=StreetNetworkPathType.BEGINNING_FALLBACK,
                request_id="{}_fallback_orig".format(request_id),
            )

            context.dest_fallback_durations_pool = FallbackDurationsPool(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_dest_obj,
                modes=requested_arr_modes_with_pt,
                proximities_by_crowfly_pool=context.
                dest_proximities_by_crowfly,
                places_free_access=context.dest_places_free_access,
                direct_paths_by_mode=context.direct_paths_by_mode,
                request=request,
                direct_path_type=StreetNetworkPathType.ENDING_FALLBACK,
                request_id="{}_fallback_dest".format(request_id),
            )

        pt_journey_pool = PtJourneyPool(
            future_manager=future_manager,
            instance=instance,
            requested_orig_obj=context.requested_orig_obj,
            requested_dest_obj=context.requested_dest_obj,
            streetnetwork_path_pool=context.streetnetwork_path_pool,
            krakens_call=krakens_call,
            orig_fallback_durations_pool=context.orig_fallback_durations_pool,
            dest_fallback_durations_pool=context.dest_fallback_durations_pool,
            request=request,
            request_type=request_type,
            request_id="{}_ptjourney".format(request_id),
        )

        pt_journey_elements = wait_and_build_crowflies(
            requested_orig_obj=context.requested_orig_obj,
            requested_dest_obj=context.requested_dest_obj,
            pt_journey_pool=pt_journey_pool,
            has_valid_direct_paths=context.streetnetwork_path_pool.
            has_valid_direct_paths(),
            orig_places_free_access=context.orig_places_free_access,
            dest_places_free_acces=context.dest_places_free_access,
            orig_fallback_durations_pool=context.orig_fallback_durations_pool,
            dest_fallback_durations_pool=context.dest_fallback_durations_pool,
        )

        context.journeys_to_modes.update(
            self._map_journeys_to_modes(pt_journey_elements))

        # At the stage, all types of journeys have been computed thus we build the final result here
        res = []
        if context.partial_response_is_empty:
            for mode in requested_direct_path_modes:
                dp = context.direct_paths_by_mode.get(mode).wait_and_get()
                if getattr(dp, "journeys", None):
                    res.append(dp)

        # pt_journeys may contain None and res must be a list of protobuf journey
        res.extend(
            (j.pt_journeys for j in pt_journey_elements if j.pt_journeys))

        check_final_results_or_raise(res, context.orig_fallback_durations_pool,
                                     context.dest_fallback_durations_pool)

        for r in res:
            fill_uris(r)

        context.partial_response_is_empty = False

        # add SN feed publishers
        context.streetnetwork_path_pool.add_feed_publishers(
            request, requested_direct_path_modes, res)

        return res
Exemplo n.º 22
0
 def make_location(self, obj):
     coord = get_pt_object_coord(obj)
     return type_pb2.LocationContext(place="",
                                     access_duration=0,
                                     lon=round(coord.lon, 5),
                                     lat=round(coord.lat, 5))
Exemplo n.º 23
0
def build_ridesharing_journeys(from_pt_obj, to_pt_obj, period_extremity,
                               instance):
    from_coord = get_pt_object_coord(from_pt_obj)
    to_coord = get_pt_object_coord(to_pt_obj)
    from_str = "{},{}".format(from_coord.lat, from_coord.lon)
    to_str = "{},{}".format(to_coord.lat, to_coord.lon)
    try:
        rsjs, fps = instance.get_ridesharing_journeys_with_feed_publishers(
            from_str, to_str, period_extremity)
    except Exception as e:
        logging.exception(
            'Error while retrieving ridesharing ads and feed_publishers from %s to %s: {}',
            from_str, to_str)
        new_relic.record_custom_event('ridesharing_internal_failure',
                                      {'message': str(e)})
        rsjs = []
        fps = []

    pb_rsjs = []
    pb_tickets = []
    pb_feed_publishers = [_make_pb_fp(fp) for fp in fps if fp is not None]

    for rsj in rsjs:
        pb_rsj = response_pb2.Journey()
        pb_rsj_pickup = instance.georef.place("{};{}".format(
            rsj.pickup_place.lon, rsj.pickup_place.lat))
        pb_rsj_dropoff = instance.georef.place("{};{}".format(
            rsj.dropoff_place.lon, rsj.dropoff_place.lat))
        pickup_coord = get_pt_object_coord(pb_rsj_pickup)
        dropoff_coord = get_pt_object_coord(pb_rsj_dropoff)

        pb_rsj.requested_date_time = period_extremity.datetime
        pb_rsj.departure_date_time = rsj.pickup_date_time
        pb_rsj.arrival_date_time = rsj.dropoff_date_time
        pb_rsj.tags.append('ridesharing')

        # start teleport section
        start_teleport_section = pb_rsj.sections.add()
        start_teleport_section.id = "section_{}".format(
            six.text_type(generate_id()))
        start_teleport_section.type = response_pb2.CROW_FLY
        start_teleport_section.street_network.mode = response_pb2.Walking
        start_teleport_section.origin.CopyFrom(from_pt_obj)
        start_teleport_section.destination.CopyFrom(pb_rsj_pickup)
        start_teleport_section.length = int(
            crowfly_distance_between(from_coord, pickup_coord))
        start_teleport_section.duration = 0
        start_teleport_section.shape.extend([from_coord, pickup_coord])
        start_teleport_section.begin_date_time = rsj.pickup_date_time
        start_teleport_section.end_date_time = rsj.pickup_date_time
        # report value to journey
        pb_rsj.distances.walking += start_teleport_section.length

        # real ridesharing section
        rs_section = pb_rsj.sections.add()
        rs_section.id = "section_{}".format(six.text_type(generate_id()))
        rs_section.type = response_pb2.RIDESHARING
        rs_section.origin.CopyFrom(pb_rsj_pickup)
        rs_section.destination.CopyFrom(pb_rsj_dropoff)
        rs_section.additional_informations.append(
            response_pb2.HAS_DATETIME_ESTIMATED)

        rs_section.ridesharing_information.operator = rsj.metadata.system_id
        rs_section.ridesharing_information.network = rsj.metadata.network
        if rsj.available_seats is not None:
            rs_section.ridesharing_information.seats.available = rsj.available_seats
        if rsj.total_seats is not None:
            rs_section.ridesharing_information.seats.total = rsj.total_seats
        if rsj.driver.alias:
            rs_section.ridesharing_information.driver.alias = rsj.driver.alias
        if rsj.driver.image:
            rs_section.ridesharing_information.driver.image = rsj.driver.image
        if rsj.driver.gender is not None:
            if rsj.driver.gender == Gender.MALE:
                rs_section.ridesharing_information.driver.gender = response_pb2.MALE
            elif rsj.driver.gender == Gender.FEMALE:
                rs_section.ridesharing_information.driver.gender = response_pb2.FEMALE
        if rsj.driver.rate is not None and rsj.driver.rate_count:
            rs_section.ridesharing_information.driver.rating.value = rsj.driver.rate
        if rsj.driver.rate_count:
            rs_section.ridesharing_information.driver.rating.count = rsj.driver.rate_count
        if rsj.metadata.rating_scale_min is not None and rsj.metadata.rating_scale_max is not None:
            rs_section.ridesharing_information.driver.rating.scale_min = rsj.metadata.rating_scale_min
            rs_section.ridesharing_information.driver.rating.scale_max = rsj.metadata.rating_scale_max

        if rsj.ridesharing_ad:
            l = rs_section.ridesharing_information.links.add()
            l.key = "ridesharing_ad"
            l.href = rsj.ridesharing_ad

        # TODO CO2 = length * coeffCar / (totalSeats  + 1)
        rs_section.length = rsj.distance

        rs_section.shape.extend(rsj.shape)

        rs_section.duration = rsj.dropoff_date_time - rsj.pickup_date_time
        rs_section.begin_date_time = rsj.pickup_date_time
        rs_section.end_date_time = rsj.dropoff_date_time
        # report values to journey
        pb_rsj.distances.ridesharing += rs_section.length
        pb_rsj.duration += rs_section.duration
        pb_rsj.durations.total += rs_section.duration
        pb_rsj.durations.ridesharing += rs_section.duration

        # end teleport section
        end_teleport_section = pb_rsj.sections.add()
        end_teleport_section.id = "section_{}".format(
            six.text_type(generate_id()))
        end_teleport_section.type = response_pb2.CROW_FLY
        end_teleport_section.street_network.mode = response_pb2.Walking
        end_teleport_section.origin.CopyFrom(pb_rsj_dropoff)
        end_teleport_section.destination.CopyFrom(to_pt_obj)
        end_teleport_section.length = int(
            crowfly_distance_between(dropoff_coord, to_coord))
        end_teleport_section.duration = 0
        end_teleport_section.shape.extend([dropoff_coord, to_coord])
        end_teleport_section.begin_date_time = rsj.dropoff_date_time
        end_teleport_section.end_date_time = rsj.dropoff_date_time
        # report value to journey
        pb_rsj.distances.walking += end_teleport_section.length

        # create ticket associated
        ticket = response_pb2.Ticket()
        ticket.id = "ticket_{}".format(six.text_type(generate_id()))
        ticket.name = "ridesharing_price_{}".format(ticket.id)
        ticket.found = True
        ticket.comment = "Ridesharing price for section {}".format(
            rs_section.id)
        ticket.section_id.extend([rs_section.id])
        # also add fare to journey
        ticket.cost.value = rsj.price
        pb_rsj.fare.total.value = ticket.cost.value
        ticket.cost.currency = rsj.currency
        pb_rsj.fare.total.currency = rsj.currency
        pb_rsj.fare.found = True
        pb_rsj.fare.ticket_id.extend([ticket.id])

        pb_tickets.append(ticket)
        pb_rsjs.append(pb_rsj)

    return pb_rsjs, pb_tickets, pb_feed_publishers
Exemplo n.º 24
0
def _get_coord(pt_object):
    coord = get_pt_object_coord(pt_object)
    return 'geo!{lat},{lon}'.format(lat=coord.lat, lon=coord.lon)