コード例 #1
0
ファイル: new_default.py プロジェクト: niko64fx/navitia
    def call_kraken(self, request_type, request, instance, krakens_call):
        """
        For all krakens_call, call the kraken and aggregate the responses

        return the list of all responses
        """
        # TODO: handle min_alternative_journeys
        # TODO: call first bss|bss and do not call walking|walking if no bss in first results

        resp = []
        logger = logging.getLogger(__name__)
        for dep_mode, arr_mode in krakens_call:
            pb_request = create_pb_request(request_type, request, dep_mode,
                                           arr_mode)
            self.nb_kraken_calls += 1

            local_resp = instance.send_and_receive(pb_request)

            # for log purpose we put and id in each journeys
            for idx, j in enumerate(local_resp.journeys):
                j.internal_id = "{resp}-{j}".format(resp=self.nb_kraken_calls,
                                                    j=idx)

            resp.append(local_resp)
            logger.debug("for mode %s|%s we have found %s journeys", dep_mode,
                         arr_mode, len(local_resp.journeys))

        for r in resp:
            fill_uris(r)
        return resp
コード例 #2
0
ファイル: new_default.py プロジェクト: vmulard/navitia
    def call_kraken(self, request_type, request, instance, krakens_call):
        """
        For all krakens_call, call the kraken and aggregate the responses

        return the list of all responses
        """
        # TODO: handle min_alternative_journeys
        # TODO: call first bss|bss and do not call walking|walking if no bss in first results
        resp = []
        logger = logging.getLogger(__name__)
        futures = []

        def worker(dep_mode, arr_mode, instance, request, request_id):
            return (dep_mode, arr_mode, instance.send_and_receive(request, request_id=request_id))

        pool = gevent.pool.Pool(app.config.get('GREENLET_POOL_SIZE', 3))
        for dep_mode, arr_mode in krakens_call:
            pb_request = create_pb_request(request_type, request, dep_mode, arr_mode)
            #we spawn a new green thread, it won't have access to our thread local request object so we set request_id
            futures.append(pool.spawn(worker, dep_mode, arr_mode, instance, pb_request, request_id=flask.request.id))

        for future in gevent.iwait(futures):
            dep_mode, arr_mode, local_resp = future.get()
            # for log purpose we put and id in each journeys
            self.nb_kraken_calls += 1
            for idx, j in enumerate(local_resp.journeys):
                j.internal_id = "{resp}-{j}".format(resp=self.nb_kraken_calls, j=idx)
            if 'ridesharing' in dep_mode or 'ridesharing' in arr_mode:
                _switch_back_to_ridesharing(local_resp)
            fill_uris(local_resp)
            resp.append(local_resp)
            logger.debug("for mode %s|%s we have found %s journeys", dep_mode, arr_mode, len(local_resp.journeys))

        return resp
コード例 #3
0
    def call_kraken(self,
                    request_type,
                    request,
                    instance,
                    krakens_call,
                    context=None):
        """
        For all krakens_call, call the kraken and aggregate the responses

        return the list of all responses
        """
        # TODO: handle min_alternative_journeys
        # TODO: call first bss|bss and do not call walking|walking if no bss in first results
        record_custom_parameter('scenario', 'new_default')
        resp = []
        logger = logging.getLogger(__name__)
        futures = []
        reqctx = copy_flask_request_context()

        def worker(dep_mode, arr_mode, instance, request, flask_request_id):
            with copy_context_in_greenlet_stack(reqctx):
                return (
                    dep_mode,
                    arr_mode,
                    instance.send_and_receive(
                        request, flask_request_id=flask_request_id),
                )

        pool = gevent.pool.Pool(app.config.get('GREENLET_POOL_SIZE', 3))
        for dep_mode, arr_mode, direct_path_type in krakens_call:
            pb_request = create_pb_request(request_type, request, dep_mode,
                                           arr_mode, direct_path_type)
            # we spawn a new greenlet, it won't have access to our thread local request object so we pass the request_id
            futures.append(
                pool.spawn(worker,
                           dep_mode,
                           arr_mode,
                           instance,
                           pb_request,
                           flask_request_id=flask.request.id))

        for future in gevent.iwait(futures):
            dep_mode, arr_mode, local_resp = future.get()
            # for log purpose we put and id in each journeys
            self.nb_kraken_calls += 1
            for idx, j in enumerate(local_resp.journeys):
                j.internal_id = "{resp}-{j}".format(resp=self.nb_kraken_calls,
                                                    j=idx)

            if dep_mode == 'ridesharing':
                switch_back_to_ridesharing(local_resp, True)
            if arr_mode == 'ridesharing':
                switch_back_to_ridesharing(local_resp, False)

            fill_uris(local_resp)
            resp.append(local_resp)
            logger.debug("for mode %s|%s we have found %s journeys", dep_mode,
                         arr_mode, len(local_resp.journeys))

        return resp
コード例 #4
0
ファイル: default.py プロジェクト: homerquan/navitia
    def call_kraken(self, req, instance, tag=None):
        resp = None

        """
            for all combinaison of departure and arrival mode we call kraken
        """
        logger = logging.getLogger(__name__)
        # filter walking if bss in mode ?
        for o_mode, d_mode in itertools.product(self.origin_modes, self.destination_modes):
            req.journeys.streetnetwork_params.origin_mode = o_mode
            req.journeys.streetnetwork_params.destination_mode = d_mode
            local_resp = instance.send_and_receive(req)
            if local_resp.response_type == response_pb2.ITINERARY_FOUND:

                # if a specific tag was provided, we tag the journeys
                # and we don't call the qualifier, it will be done after
                # with the journeys from the previous query
                if tag:
                    for j in local_resp.journeys:
                        j.type = tag
                else:
                    #we qualify the journeys
                    request_type = "arrival" if req.journeys.clockwise else "departure"
                    qualifier_one(local_resp.journeys, request_type)

                if not resp:
                    resp = local_resp
                else:
                    self.merge_response(resp, local_resp)
            if not resp:
                resp = local_resp
            logger.debug("for mode %s|%s we have found %s journeys: %s", o_mode, d_mode, len(local_resp.journeys), [j.type for j in local_resp.journeys])

        fill_uris(resp)
        return resp
コード例 #5
0
    def call_kraken(self, request_type, request, instance, krakens_call):
        """
        For all krakens_call, call the kraken and aggregate the responses

        return the list of all responses
        """
        logger = logging.getLogger(__name__)
        logger.debug('datetime: %s', request['datetime'])

        for dep_mode, arr_mode in krakens_call:
            if dep_mode not in g.origins_fallback:
                g.origins_fallback[dep_mode] = instance.georef.get_stop_points(request['origin'],
                        dep_mode,
                        get_max_fallback_duration(request, dep_mode))
                #logger.debug('origins %s: %s', dep_mode, g.origins_fallback[dep_mode])

            if arr_mode not in g.destinations_fallback:
                g.destinations_fallback[arr_mode] = instance.georef.get_stop_points(request['destination'],
                        arr_mode,
                        get_max_fallback_duration(request, arr_mode), reverse=True)
                #logger.debug('destinations %s: %s', arr_mode, g.destinations_fallback[arr_mode])

        if not g.requested_origin:
            g.requested_origin = instance.georef.place(request['origin'])
        if not g.requested_destination:
            g.requested_destination = instance.georef.place(request['destination'])

        resp = []
        journey_parameters = create_parameters(request)
        for dep_mode, arr_mode in krakens_call:
            #todo: this is probably shared between multiple thread
            self.nb_kraken_calls += 1

            local_resp = instance.planner.journeys(g.origins_fallback[dep_mode],
                                                   g.destinations_fallback[arr_mode],
                                                   request['datetime'],
                                                   request['clockwise'],
                                                   journey_parameters)

            # for log purpose we put and id in each journeys
            for idx, j in enumerate(local_resp.journeys):
                j.internal_id = "{resp}-{j}".format(resp=self.nb_kraken_calls, j=idx)

            for journey in local_resp.journeys:
                build_journey(journey,
                                   g.requested_origin,
                                   g.requested_destination,
                                   g.origins_fallback[dep_mode],
                                   g.destinations_fallback[arr_mode])

            resp.append(local_resp)
            logger.debug("for mode %s|%s we have found %s journeys", dep_mode, arr_mode, len(local_resp.journeys))

        for r in resp:
            fill_uris(r)
        return resp
コード例 #6
0
ファイル: default.py プロジェクト: qinwenshi/navitia
    def call_kraken(self, req, instance, tag=None):
        resp = None

        """
            for all combinaison of departure and arrival mode we call kraken
        """
        logger = logging.getLogger(__name__)
        futures = []

        def worker(o_mode, d_mode, instance, request, request_id):
            return (o_mode, d_mode, instance.send_and_receive(request, request_id=request_id))

        pool = gevent.pool.Pool(current_app.config.get('GREENLET_POOL_SIZE', 3))
        for o_mode, d_mode in itertools.product(self.origin_modes, self.destination_modes):
            #since we use multiple green thread we have to copy the request
            local_req = copy.deepcopy(req)
            local_req.journeys.streetnetwork_params.origin_mode = o_mode
            local_req.journeys.streetnetwork_params.destination_mode = d_mode
            if o_mode == 'car' or (is_admin(req.journeys.origin[0].place) and is_admin(req.journeys.destination[0].place)):
                # we don't want direct path for car or for admin to admin journeys
                req.journeys.streetnetwork_params.enable_direct_path = False
            else:
                req.journeys.streetnetwork_params.enable_direct_path = True
            futures.append(pool.spawn(worker, o_mode, d_mode, instance, local_req, request_id=flask.request.id))

        for future in gevent.iwait(futures):
            o_mode, d_mode, local_resp = future.get()
            if local_resp.response_type == response_pb2.ITINERARY_FOUND:

                # if a specific tag was provided, we tag the journeys
                # and we don't call the qualifier, it will be done after
                # with the journeys from the previous query
                if tag:
                    for j in local_resp.journeys:
                        j.type = tag
                else:
                    #we qualify the journeys
                    request_type = "arrival" if req.journeys.clockwise else "departure"
                    qualifier_one(local_resp.journeys, request_type)

                fill_uris(local_resp)
                if not resp:
                    resp = local_resp
                else:
                    self.merge_response(resp, local_resp)
            if not resp:
                resp = local_resp
            logger.debug("for mode %s|%s we have found %s journeys: %s", o_mode, d_mode, len(local_resp.journeys), [j.type for j in local_resp.journeys])

        return resp
コード例 #7
0
ファイル: distributed.py プロジェクト: qinwenshi/navitia
    def _compute_all(future_manager, request, instance, krakens_call):
        """
        For all krakens_call, call the kraken and aggregate the responses

        return the list of all responses
        """
        logger = logging.getLogger(__name__)
        logger.debug('request datetime: %s', request['datetime'])

        requested_dep_modes = {mode for mode, _ in krakens_call}
        requested_arr_modes = {mode for _, mode in krakens_call}

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

        requested_orig = PlaceByUri(future_manager=future_manager,
                                    instance=instance,
                                    uri=request['origin'])
        requested_dest = PlaceByUri(future_manager=future_manager,
                                    instance=instance,
                                    uri=request['destination'])

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

        streetnetwork_path_pool = StreetNetworkPathPool(
            future_manager=future_manager, instance=instance)
        period_extremity = PeriodExtremity(request['datetime'],
                                           request['clockwise'])

        # we launch direct path asynchronously
        for mode in requested_dep_modes:
            streetnetwork_path_pool.add_async_request(
                requested_orig_obj=requested_orig_obj,
                requested_dest_obj=requested_dest_obj,
                mode=mode,
                period_extremity=period_extremity,
                request=request,
                streetnetwork_path_type=StreetNetworkPathType.DIRECT)

        # 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:
            return [
                streetnetwork_path_pool.wait_and_get(
                    requested_orig_obj=requested_orig_obj,
                    requested_dest_obj=requested_dest_obj,
                    mode=mode,
                    request=request,
                    period_extremity=period_extremity,
                    streetnetwork_path_type=StreetNetworkPathType.DIRECT)
                for mode in requested_dep_modes
            ]

        # 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
        direct_paths_by_mode = streetnetwork_path_pool.get_all_direct_paths()

        orig_proximities_by_crowfly = ProximitiesByCrowflyPool(
            future_manager=future_manager,
            instance=instance,
            requested_place_obj=requested_orig_obj,
            modes=requested_dep_modes,
            request=request,
            direct_paths_by_mode=direct_paths_by_mode)

        dest_proximities_by_crowfly = ProximitiesByCrowflyPool(
            future_manager=future_manager,
            instance=instance,
            requested_place_obj=requested_dest_obj,
            modes=requested_arr_modes,
            request=request,
            direct_paths_by_mode=direct_paths_by_mode)

        orig_places_free_access = PlacesFreeAccess(
            future_manager=future_manager,
            instance=instance,
            requested_place_obj=requested_orig_obj)
        dest_places_free_access = PlacesFreeAccess(
            future_manager=future_manager,
            instance=instance,
            requested_place_obj=requested_dest_obj)

        orig_fallback_durations_pool = FallbackDurationsPool(
            future_manager=future_manager,
            instance=instance,
            requested_place_obj=requested_orig_obj,
            modes=requested_dep_modes,
            proximities_by_crowfly_pool=orig_proximities_by_crowfly,
            places_free_access=orig_places_free_access,
            direct_paths_by_mode=direct_paths_by_mode,
            request=request,
            direct_path_type=StreetNetworkPathType.BEGINNING_FALLBACK)

        dest_fallback_durations_pool = FallbackDurationsPool(
            future_manager=future_manager,
            instance=instance,
            requested_place_obj=requested_dest_obj,
            modes=requested_arr_modes,
            proximities_by_crowfly_pool=dest_proximities_by_crowfly,
            places_free_access=dest_places_free_access,
            direct_paths_by_mode=direct_paths_by_mode,
            request=request,
            direct_path_type=StreetNetworkPathType.ENDING_FALLBACK)

        pt_journey_pool = PtJourneyPool(
            future_manager=future_manager,
            instance=instance,
            requested_orig_obj=requested_orig_obj,
            requested_dest_obj=requested_dest_obj,
            streetnetwork_path_pool=streetnetwork_path_pool,
            krakens_call=krakens_call,
            orig_fallback_durations_pool=orig_fallback_durations_pool,
            dest_fallback_durations_pool=dest_fallback_durations_pool,
            request=request)

        completed_pt_journeys = wait_and_complete_pt_journey(
            future_manager=future_manager,
            requested_orig_obj=requested_orig_obj,
            requested_dest_obj=requested_dest_obj,
            pt_journey_pool=pt_journey_pool,
            streetnetwork_path_pool=streetnetwork_path_pool,
            orig_places_free_access=orig_places_free_access,
            dest_places_free_access=dest_places_free_access,
            orig_fallback_durations_pool=orig_fallback_durations_pool,
            dest_fallback_durations_pool=dest_fallback_durations_pool,
            request=request)

        # At the stage, all types of journeys have been computed thus we build the final result here
        res = []

        for mode in requested_dep_modes:
            dp = direct_paths_by_mode.get(mode).wait_and_get()
            if getattr(dp, "journeys", None):
                res.append(dp)

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

        check_final_results_or_raise(res, orig_fallback_durations_pool,
                                     dest_fallback_durations_pool)

        for r in res:
            fill_uris(r)
        return res
コード例 #8
0
ファイル: distributed.py プロジェクト: cuulee/navitia
    def _compute_all(self, future_manager, request, instance, krakens_call,
                     context):
        """
        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'])

        requested_dep_modes = {mode for mode, _, _ in krakens_call}
        requested_arr_modes = {mode for _, mode, _ in krakens_call}

        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'])
            context.requested_dest = PlaceByUri(future_manager=future_manager,
                                                instance=instance,
                                                uri=request['destination'])

            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_dep_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,
                )

            # 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:
                return [
                    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_dep_modes
                ]

            # 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(
            )

            context.orig_proximities_by_crowfly = ProximitiesByCrowflyPool(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_orig_obj,
                modes=requested_dep_modes,
                request=request,
                direct_paths_by_mode=context.direct_paths_by_mode,
                max_nb_crowfly_by_mode=request['max_nb_crowfly_by_mode'],
            )

            context.dest_proximities_by_crowfly = ProximitiesByCrowflyPool(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_dest_obj,
                modes=requested_arr_modes,
                request=request,
                direct_paths_by_mode=context.direct_paths_by_mode,
                max_nb_crowfly_by_mode=request['max_nb_crowfly_by_mode'],
            )

            context.orig_places_free_access = PlacesFreeAccess(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_orig_obj)
            context.dest_places_free_access = PlacesFreeAccess(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_dest_obj)

            context.orig_fallback_durations_pool = FallbackDurationsPool(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_orig_obj,
                modes=requested_dep_modes,
                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,
            )

            context.dest_fallback_durations_pool = FallbackDurationsPool(
                future_manager=future_manager,
                instance=instance,
                requested_place_obj=context.requested_dest_obj,
                modes=requested_arr_modes,
                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,
            )

        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,
        )

        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_dep_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

        return res
コード例 #9
0
    def _compute_isochrone_common(self, future_manager, request, instance,
                                  krakens_call, request_type):
        logger = logging.getLogger(__name__)
        logger.debug('request datetime: %s', request['datetime'])

        isochrone_center = request['origin'] or request['destination']

        mode_getter = operator.itemgetter(0 if request['origin'] else 1)
        requested_modes = {mode_getter(call) for call in krakens_call}

        logger.debug('requesting places by uri orig: %s', isochrone_center)

        requested_orig = PlaceByUri(future_manager=future_manager,
                                    instance=instance,
                                    uri=isochrone_center)

        requested_obj = get_entry_point_or_raise(requested_orig,
                                                 isochrone_center)

        direct_paths_by_mode = {}

        proximities_by_crowfly = ProximitiesByCrowflyPool(
            future_manager=future_manager,
            instance=instance,
            requested_place_obj=requested_obj,
            modes=requested_modes,
            request=request,
            direct_paths_by_mode=direct_paths_by_mode,
            max_nb_crowfly_by_mode=request.get('max_nb_crowfly_by_mode', {}),
        )

        places_free_access = PlacesFreeAccess(
            future_manager=future_manager,
            instance=instance,
            requested_place_obj=requested_obj)

        direct_path_type = (StreetNetworkPathType.BEGINNING_FALLBACK
                            if request['origin'] else
                            StreetNetworkPathType.ENDING_FALLBACK)

        fallback_durations_pool = FallbackDurationsPool(
            future_manager=future_manager,
            instance=instance,
            requested_place_obj=requested_obj,
            modes=requested_modes,
            proximities_by_crowfly_pool=proximities_by_crowfly,
            places_free_access=places_free_access,
            direct_paths_by_mode=direct_paths_by_mode,
            request=request,
            direct_path_type=direct_path_type,
        )

        # We don't need requested_orig_obj or requested_dest_obj for isochrone
        pt_journey_args = {
            "future_manager": future_manager,
            "instance": instance,
            "requested_orig_obj": None,
            "requested_dest_obj": None,
            "streetnetwork_path_pool": None,
            "krakens_call": krakens_call,
            "request": request,
            "request_type": request_type,
            "isochrone_center": isochrone_center,
        }
        if request['origin']:
            pt_journey_args.update({
                "orig_fallback_durations_pool": fallback_durations_pool,
                "dest_fallback_durations_pool": None
            })
        else:
            pt_journey_args.update({
                "orig_fallback_durations_pool":
                None,
                "dest_fallback_durations_pool":
                fallback_durations_pool
            })

        pt_journey_pool = PtJourneyPool(**pt_journey_args)

        res = []
        for (dep_mode, arr_mode, future_pt_journey) in pt_journey_pool:
            logger.debug(
                "waiting for pt journey starts with %s and ends with %s",
                dep_mode, arr_mode)
            pt_journeys = wait_and_get_pt_journeys(future_pt_journey, False)
            if pt_journeys:
                res.append(pt_journeys)

            for r in res:
                fill_uris(r)

        # Graphical isochrone returns one response, not a list of responses
        if request_type == type_pb2.graphical_isochrone:
            return res[0]

        return res
コード例 #10
0
ファイル: experimental.py プロジェクト: ballouche/navitia
    def call_kraken(self, request_type, request, instance, krakens_call):
        """
        For all krakens_call, call the kraken and aggregate the responses

        return the list of all responses
        """
        logger = logging.getLogger(__name__)
        logger.debug('datetime: %s', request['datetime'])

        for dep_mode, arr_mode in krakens_call:
            if dep_mode not in g.origins_fallback:
                g.origins_fallback[dep_mode] = instance.georef.get_stop_points(request['origin'],
                        dep_mode,
                        get_max_fallback_duration(request, dep_mode))

                #logger.debug('origins %s: %s', dep_mode, g.origins_fallback[dep_mode])

            if arr_mode not in g.destinations_fallback:
                g.destinations_fallback[arr_mode] = instance.georef.get_stop_points(request['destination'],
                        arr_mode,
                        get_max_fallback_duration(request, arr_mode), reverse=True)
                #logger.debug('destinations %s: %s', arr_mode, g.destinations_fallback[arr_mode])

        if not g.requested_origin:
            g.requested_origin = instance.georef.place(request['origin'])
        if not g.requested_destination:
            g.requested_destination = instance.georef.place(request['destination'])

        resp = []
        journey_parameters = create_parameters(request)
        for dep_mode, arr_mode in krakens_call:
            #todo: this is probably shared between multiple thread
            self.nb_kraken_calls += 1
            direct_path = self._get_direct_path(instance,
                                                dep_mode,
                                                g.requested_origin,
                                                g.requested_destination,
                                                request['datetime'],
                                                request['clockwise'])
            if direct_path.journeys:
                journey_parameters.direct_path_duration = direct_path.journeys[0].durations.total
                resp.append(direct_path)
            else:
                journey_parameters.direct_path_duration = None

            local_resp = instance.planner.journeys(g.origins_fallback[dep_mode],
                                                   g.destinations_fallback[arr_mode],
                                                   request['datetime'],
                                                   request['clockwise'],
                                                   journey_parameters)

            if local_resp.HasField(b"error") and local_resp.error.id == response_pb2.Error.error_id.Value('no_solution') \
                    and direct_path.journeys:
                local_resp.ClearField(b"error")

            if local_resp.HasField(b"error"):
                return [local_resp]

            # for log purpose we put and id in each journeys
            for idx, j in enumerate(local_resp.journeys):
                j.internal_id = "{resp}-{j}".format(resp=self.nb_kraken_calls, j=idx)

            for journey in local_resp.journeys:
                build_journey(journey,
                                   g.requested_origin,
                                   g.requested_destination,
                                   g.origins_fallback[dep_mode],
                                   g.destinations_fallback[arr_mode])

            resp.append(local_resp)
            logger.debug("for mode %s|%s we have found %s journeys", dep_mode, arr_mode, len(local_resp.journeys))
            logger.debug("for mode %s|%s we have found %s direct path", dep_mode, arr_mode, len(direct_path.journeys))

        for r in resp:
            fill_uris(r)
        return resp
コード例 #11
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 not self.is_type_only(direct_path_type)
        }
        requested_arr_modes_with_pt = {
            mode for _, mode, direct_path_type in krakens_call if not self.is_type_only(direct_path_type)
        }

        # 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 self.is_type_only(direct_path_type)
        }
        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 public transport is not requested, there is no need to continue,
            # we return all direct path without pt
            if request['max_duration'] == 0 or request.get('direct_path', "") in (
                "only",
                "only_with_alternatives",
            ):
                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
コード例 #12
0
    def call_kraken(self, request_type, request, instance, krakens_call):
        """
        For all krakens_call, call the kraken and aggregate the responses

        return the list of all responses
        """
        logger = logging.getLogger(__name__)
        logger.debug('datetime: %s', request['datetime'])

        # odt_stop_points is a set of stop_point.uri with is_zonal = true used to manage tad_zonal
        odt_stop_points = set()

        # crowfly_stop_points is a set of stop_point.uri used to create a crowfly section.
        crowfly_stop_points = set()

        if not g.requested_origin:
            g.requested_origin = instance.georef.place(request['origin'])
            if not g.requested_origin:
                r = self._make_error_response(
                    "The entry point: {} is not valid".format(
                        request['origin']), response_pb2.Error.unknown_object)
                return [r]

        if not g.requested_destination:
            g.requested_destination = instance.georef.place(
                request['destination'])
            if not g.requested_destination:
                r = self._make_error_response(
                    "The entry point: {} is not valid".format(
                        request['destination']),
                    response_pb2.Error.unknown_object)
                return [r]

        worker = AsyncWorker(instance, krakens_call, request)

        resp = []

        # Now we compute the direct path with all requested departure
        # mode their time will be used to initialized our PT calls and
        # to bound the fallback duration of the first section.
        futures = worker.get_direct_path_futures(
            g.fallback_direct_path, g.requested_origin,
            g.requested_destination, request['datetime'], request['clockwise'],
            False, {mode
                    for mode, _ in krakens_call})
        for future in gevent.iwait(futures):
            resp_key, resp_direct_path = future.get()
            g.fallback_direct_path[resp_key] = resp_direct_path
            if resp_direct_path.journeys:
                resp_direct_path.journeys[0].internal_id = str(generate_id())
                resp.append(resp_direct_path)

        if request.get('max_duration', 0):
            direct_path_duration_by_mode = make_direct_path_duration_by_mode(
                g.fallback_direct_path)

            # Get all stop_points around the requested origin within a crowfly range
            # Calls on origins and destinations are asynchronous
            orig_futures, dest_futures = worker.get_crowfly_futures(
                g.requested_origin, g.requested_destination,
                direct_path_duration_by_mode)
            gevent.joinall(orig_futures + dest_futures)
            for future in orig_futures:
                g.origins_places_crowfly.update(future.get())
            for future in dest_futures:
                g.destinations_places_crowfly.update(future.get())

            # Once we get crow fly stop points with origins and destinations, we start
            # the computation NM: the fallback matrix which contains the arrival duration for crowfly stop_points
            # from origin/destination
            # Ex:
            #                    stop_point1   stop_point2  stop_point3
            # request_origin_1     86400(s)      43200(s)     21600(s)
            # As a side note this won't work the day when our ETA will be impacted by the datetime of the journey,
            # at least for the arrival when doing a "departure after" request.
            orig_futures, dest_futures = worker.get_routing_matrix_futures(
                g.requested_origin, g.requested_destination,
                g.origins_places_crowfly, g.destinations_places_crowfly,
                direct_path_duration_by_mode)
            gevent.joinall(orig_futures + dest_futures)
            for future in orig_futures:
                g.origins_fallback.update(future.get())
            for future in dest_futures:
                g.destinations_fallback.update(future.get())

            # In Some special cases, like "odt" or "departure(arrive) from(to) a stop_area",
            # the first(last) section should be treated differently
            orig_futures, dest_futures = worker.get_update_crowfly_duration_futures(
            )
            gevent.joinall(orig_futures + dest_futures)

            def _updater(_futures, fb, crowfly_stop_points, odt_stop_points):
                for f in _futures:
                    crowfly_res, odt_res, fb_res = f.get()
                    crowfly_stop_points |= crowfly_res
                    odt_stop_points |= odt_res
                    for mode in (mode for mode in fb_res if mode in fb):
                        fb.merge_reached_values(mode, fb_res[mode])

            _updater(orig_futures, g.origins_fallback, crowfly_stop_points,
                     odt_stop_points)
            _updater(dest_futures, g.destinations_fallback,
                     crowfly_stop_points, odt_stop_points)

            # We update the fallback duration matrix if the requested origin/destination is also
            # present in the fallback duration matrix, which means from stop_point_1 to itself, it takes 0 second
            # Ex:
            #                stop_point1   stop_point2  stop_point3
            # stop_point_1         0(s)       ...          ...
            for dep_mode, arr_mode in krakens_call:
                g.origins_fallback.reset_if_exist(dep_mode,
                                                  g.requested_origin.uri)
                g.destinations_fallback.reset_if_exist(
                    arr_mode, g.requested_destination.uri)

        # Here starts the computation for pt journey
        journey_parameters = create_parameters(request)
        futures = worker.get_pt_journey_futures(g.requested_origin,
                                                g.requested_destination,
                                                g.fallback_direct_path,
                                                g.origins_fallback,
                                                g.destinations_fallback,
                                                journey_parameters)

        response_tuples = []
        for future in gevent.iwait(futures):
            dep_mode, arr_mode, local_resp = future.get()
            if local_resp is None:
                continue
            dp_key = make_direct_path_key(dep_mode, g.requested_origin.uri,
                                          g.requested_destination.uri,
                                          request['datetime'],
                                          request['clockwise'], False)
            direct_path = g.fallback_direct_path.get(dp_key)

            if local_resp.HasField(b"error") and local_resp.error.id == response_pb2.Error.error_id.Value('no_solution') \
                    and direct_path.journeys:
                local_resp.ClearField(b"error")
            if local_resp.HasField(b"error"):
                #Here needs to modify error message of no_solution
                if len(g.origins_fallback[dep_mode]) == 0:
                    self.update_error_message(local_resp,
                                              response_pb2.Error.no_origin,
                                              "no origin point")
                elif len(g.destinations_fallback[arr_mode]) == 0:
                    self.update_error_message(
                        local_resp, response_pb2.Error.no_destination,
                        "no destination point")

                return [local_resp]

            # for log purpose we put and id in each journeys
            for j in local_resp.journeys:
                j.internal_id = str(generate_id())
                response_tuples.append((dep_mode, arr_mode, j))
            resp.append(local_resp)

        # Once the pt journey is found, we need to reconstruct the whole journey with fallback regarding the mode

        # For the sake of performance, we compute at first all fallback direct path asynchronously
        # then we update the pool of direct paths
        futures = worker.get_fallback_direct_path_futures(
            response_tuples, crowfly_stop_points, odt_stop_points)
        for future in gevent.iwait(futures):
            resp_key, resp_direct_path = future.get()
            g.fallback_direct_path[resp_key] = resp_direct_path

        # Now we construct the whole journey by concatenating the fallback direct path with the pt journey
        worker.build_journeys(response_tuples, crowfly_stop_points,
                              odt_stop_points)

        #If resp doesn't contain any response we have to add an error message
        if len(resp) == 0:
            if len(g.origins_fallback[dep_mode]) == 0 and len(
                    g.destinations_fallback[arr_mode]) == 0:
                resp.append(
                    self._make_error_response(
                        "no origin point nor destination point",
                        response_pb2.Error.no_origin_nor_destination))
            elif len(g.origins_fallback[dep_mode]) == 0:
                resp.append(
                    self._make_error_response("no origin point",
                                              response_pb2.Error.no_origin))
            elif len(g.destinations_fallback[arr_mode]) == 0:
                resp.append(
                    self._make_error_response(
                        "no destination point",
                        response_pb2.Error.no_destination))
            return resp
        for r in resp:
            fill_uris(r)
        return resp