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
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
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
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)
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
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), }
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'] }
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 []
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)
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
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
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
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
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}
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
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
def get_uri_pt_object(self, pt_object): return 'coord:{c.lon}:{c.lat}'.format(c=get_pt_object_coord(pt_object))
def _get_coord_for_matrix(pt_object): coord = get_pt_object_coord(pt_object) return {"lat": coord.lat, "lng": coord.lon}
def _pt_object_summary_isochrone(cls, pt_object): coord = get_pt_object_coord(pt_object) return [coord.lat, coord.lon, None]
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)]
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
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))
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
def _get_coord(pt_object): coord = get_pt_object_coord(pt_object) return 'geo!{lat},{lon}'.format(lat=coord.lat, lon=coord.lon)