コード例 #1
0
    def get_population_points(self, lat: float, lon: float, range_km: float, interval_km: float) \
            -> Tuple[List[Tuple[float, float]], List[float]]:
        """
        Get the coordinates of dummy wards with weights as the population density around the corresponding point.

        Both ``range_km`` and ``interval_km`` will be used for generating dummy wards.

        This method gets 3 closest ward points centered around ``(lat, lon)``,
        then use these to construct a plane to project the population density,
        which will be returned as the second element.
        """
        pop_points = self.find_closest_data_num(lat, lon, 3)
        pop_project_plane = get_plane(
            ((pop_points[0].data.lat, pop_points[0].data.lon,
              pop_points[0].data.total),
             (pop_points[1].data.lat, pop_points[1].data.lon,
              pop_points[1].data.total), (pop_points[2].data.lat,
                                          pop_points[2].data.lon,
                                          pop_points[2].data.total)))

        ret_pop_points: List[Tuple[float, float]] = []
        ret_pop_density: List[float] = []

        wards = generate_points((lat, lon), range_km, interval_km)

        for ward in wards:
            ret_pop_points.append(ward)
            ret_pop_density.append(pop_project_plane.get_z(*ward, 1))

        return ret_pop_points, ret_pop_density
コード例 #2
0
    def get_all_stop_remove_results(self, range_km: float, interval_km: float,
                                    pop_data: Optional[PopulationDataController] = None) \
            -> List[CrossStopRemovalResult]:
        """
        Try to remove each stops one by one, and return the results of the removal.

        Specify ``pop_data`` to use the population data instead of dummy agents for calculating the distances.

        This function uses ``msnmetrosim.utils.generate_points()``
         to generate simulated agents and to calculate the accessibility impact.

        The ``center_coord`` of ``msnmetrosim.utils.generate_points()`` will be the coordinates of the stop.

        Check the documentation of ``msnmetrosim.utils.generate_points()``
        for more information on ``range_km`` and ``interval_km``.

        WARNING: This method could be very expensive.

        For 1153 records, it takes ~5 mins to run.
        """
        # ThreadPoolExecutor won't help on performance boosting
        # OPTIMIZE: Try to reduce the calculation time of this
        #   - Each agent is expanding its circle to find the closest stop
        #   - Change the above to each stop expanding its circle to "touch" the closest agent instead?
        #   - Any possible use of numpy for performance boost?
        ret: List[CrossStopRemovalResult] = []

        total_count = len(self.all_data)
        progress = Progress(total_count)
        progress.start()

        for stop in self.all_data:
            stop: MMTStopsAtCross
            agents: List[Tuple[float, float]]
            weights: Optional[List[float]]

            if pop_data:
                lat, lon = stop.coordinate

                agents, weights = pop_data.get_population_points(lat, lon, range_km, interval_km)
            else:
                agents = generate_points(stop.coordinate, range_km, interval_km)
                weights = None

            rm_result = self.get_metrics_of_single_stop_removal(stop.primary, stop.secondary, agents, weights)

            ret.append(rm_result)

            progress.rec_completed_one()
            print(progress)

        return ret
コード例 #3
0
def plot_accessibility_impact_histograms(stops_name: List[Tuple[str, str]],
                                         plot_x: int, plot_y: int,
                                         range_km: float, interval_km: float,
                                         title: str):
    """
    Plot the accessibility difference of before and after removing the stops onto a figure and return it.

    Each element of ``stops_name`` contains the first and second street (order doesn't matter) name.

    ``plot_x`` x ``plot_y`` must equal to the count of ``stops_cross``.

    :param stops_name: street pair of the stops to be removed
    :param plot_x: count of plots on x axis
    :param plot_y: count of plots on y axis
    :param range_km: range for the dummy agents to generate in km
    :param interval_km: dummy agents interval in km
    :param title: title of the main plot
    """
    # pylint: disable=too-many-arguments

    # Get metrics between before and after removing the stop
    results: List[CrossStopRemovalResult] = []

    for stop in get_stops_at_cross(stops_name):
        print(f"Getting the metrics of {stop.cross_name}")
        agents = generate_points(stop.coordinate, range_km, interval_km)

        result = ctrl_stops_cross.get_metrics_of_single_stop_removal(
            stop.primary, stop.secondary, agents)
        results.append(result)

    # Plot the data
    figure = generate_accessibility_plot_canvas(plot_x, plot_y,
                                                plot_stop_accessibility_hist,
                                                results)
    figure.suptitle(
        title, y=0.99,
        fontsize=20)  # Enlarging the text and slightly reposition the title

    return figure
コード例 #4
0
def get_distance_to_stop():
    """Get the travel time to ``target_stop``."""
    # Controllers to traverse
    target_stop = ctrl_stops_cross.get_grouped_stop_by_street_names(
        "Inwood", "Open Wood")
    stop_cross_no_target = ctrl_stops_cross.duplicate(
        lambda data: data.unique_cross_id != target_stop.unique_cross_id)

    # Create simulated agents
    sim_agents = generate_points(target_stop.coordinate, 0.5, 0.02)

    # Get the distance metrics
    metrics_original = ctrl_stops_cross.get_distance_metrics_to_closest(
        sim_agents, name="Original")
    metrics_after = stop_cross_no_target.get_distance_metrics_to_closest(
        sim_agents, name="Original")

    # ----- Plot histogram
    # https://datavizpyr.com/overlapping-histograms-with-matplotlib-in-python/

    # Configure plot
    plt.figure(figsize=(10, 10))
    plt.xlabel("Distance to stop (km)", size=14)
    plt.ylabel("Agent count", size=14)
    plt.title(
        f"Distance to stop change between before and after removing {target_stop.cross_name}"
    )

    # Plot histogram
    plt.hist(metrics_original.data, bins=20, alpha=0.5, label="Original")
    plt.hist(metrics_after.data, bins=20, alpha=0.5, label="After")

    # Output plot image
    plt.legend(loc="upper right")
    plt.savefig("../assets/reports/0921-5.png")  # Save the figure
    plt.show()