File size: 6,411 Bytes
69a1ff7
fccab54
69a1ff7
35f2f48
fccab54
35f2f48
 
9528692
 
 
 
 
35f2f48
9528692
 
 
 
 
 
fccab54
69a1ff7
 
9528692
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fccab54
af955cc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fccab54
 
69a1ff7
fccab54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from typing import List, Tuple
import math
from traitlets import Float
from data_processing.get_smallAreaInfo import get_smallAreas
from data_processing.point_scoring import score_current, calc_score_line
from data_processing.get_station_coverage import get_station_coverage
from data_processing.aggregate_data import get_feature_df
import os
import pandas as pd
from pyproj import Transformer


class Data_provider():

    def __init__(self):
        self.smsv_list = get_smallAreas()
        self.df = get_feature_df()
        self.transformer_to_3057 = Transformer.from_crs("EPSG:4326", "EPSG:3057", always_xy=True)
        self.transformer_to_4326 = Transformer.from_crs("EPSG:3057", "EPSG:4326", always_xy=True)
        self.PENALTY_SCALE = 100
    

    def get_station_score(self, station_coord, w_density=1, w_income=1, w_age=1, radius=400, EPSG_4326=True):
        """
        Calculate the score for a station based on the given weights and radius.

        Parameters:
        ----------
        station_coord : tuple
            Coordinates of the station in EPSG:4326 format (north, east) = (lat, long).
        w_density : float
            Weight for the density factor.
        w_income : float
            Weight for the income factor.
        w_age : float
            Weight for the age factor.
        radius : float
            The radius (in meters) around the station to consider.
        EPSG_4326 : bool
            if a true, station coord of format EPSG:4326 is expected, else EPSG:3057

        Returns:
        -------
        dict
            Dictionary that contains total score and subscores
            {"total_score": total_score, "income_score": income_score, "age_score": age_score, "density_score": density_score}
        """
        if EPSG_4326:
            station_coord = self.__convert_to_3057(station_coord)
        cov = get_station_coverage(self.smsv_list, station_coord, radius)
        scores = score_current(station_coord, self.df, cov, w_density, w_income, w_age)
        return scores

    def __convert_to_3057(self, station_coord):
        """
        Convert coordinates from EPSG:4326 (lon, lat) to EPSG:3057 (x, y).

        Parameters:
        ----------
        station_coord : tuple
            Coordinates in EPSG:4326 format (lon, lat).

        Returns:
        -------
        tuple
            Coordinates in EPSG:3057 format (x, y).
        """
        return self.transformer_to_3057.transform(*station_coord)

    def __convert_to_4326(self, station_coord):
        """
        Convert coordinates from EPSG:3057 (x, y) to EPSG:4326 (lon, lat).

        Parameters:
        ----------
        station_coord : tuple
            Coordinates in EPSG:3057 format (x, y).

        Returns:
        -------
        tuple
            Coordinates in EPSG:4326 format (lon, lat).
        """
        return self.transformer_to_4326.transform(*station_coord)

    def line_score(self, stations_coordinates: List[Tuple[Float]], w_density=1, w_income=1, w_age=1, radius=400, EPSG_4326=True):
        """
        Calculate the total score for a transit line based on station locations and individual station scores.

        Parameters:
            stations_coordinates (List[Tuple[float]]): A list of station coordinates as (x, y) tuples.
            w_density (float): Weight for population density in scoring (default is 1).
            w_income (float): Weight for income level in scoring (default is 1).
            w_age (float): Weight for age distribution in scoring (default is 1).
            radius (float): Radius of influence for each station (default is 400 meters).
            EPSG_4326 (bool): If True, the coordinates are in EPSG:4326 and will be converted to EPSG:3057 (default is True).

        Returns:
            dict: A dictionary containing:
                - "individual_scores": Scores for each station before applying penalties.
                - "adjusted_scores": Scores for each station after applying penalties for proximity.
                - "overlap_factors": (Optional, if calc_score_line returns it) Degree of overlap between stations.
                - "total_individual_score": The aggregated score of all stations before penalties.
                - "final_score": The total line score after penalties.
        """
        coords_formatted = []
        coords_scores = []
        for coord in stations_coordinates:
            coord_formatted = self.__convert_to_3057(coord) if EPSG_4326 else coord
            coords_formatted.append(coord_formatted)
            coords_scores.append(self.get_station_score(coord_formatted, w_density, w_income, w_age, radius, EPSG_4326=False))
        result = calc_score_line(coords_formatted, coords_scores, w_density, w_income, w_age, radius)
        return result




# dummy_coord1 = (356250.0, 408250.0)  # EPSG:3057 coordinates
# dummy_coord2 = (-21.910388, 64.144947)  # EPSG:4326 coordinates
# dummy_coord3 = (358374.26032876654, 407938.72289760906) # ISN93/Lambert

# lane = [
#     (-2427839.8601560914, 9371544.591676729),
#     (-2431634.4660833703, 9372554.640815599),
#     (-2434649.232041, 9374913.131190613),
#     (-2436330.9382214467, 9375856.527340621),
#     (-2438828.8871577685, 9378030.440208027),
#     (-2439956.860815385, 9378055.050542375),
#     (-2442307.1477456186, 9379548.07749282),
#     (-2441441.6843210473, 9380909.849326741),
#     (-2441400.6670971345, 9384909.028658295),
#     (-2441962.6030647475, 9385105.911333079),
#     (-2443122.365070897, 9385984.705355423),
#     (-2441898.000937084, 9387355.706064725),
#     (-2423704.8112703268, 9387223.425517604),
#     (-2425747.4690212114, 9387959.684686847),
#     (-2433768.8998727645, 9383004.29132282),
#     (-2429552.329254474, 9382532.593247818),
#     (-2436008.4402984325, 9385453.019590447),
#     (-2438288.9979480137, 9386006.752113278),
#     (-2439449.7853847607, 9386252.855456758)]

# transformer = Transformer.from_crs("EPSG:3857", "EPSG:3057", always_xy=True)
# for i in range(len(lane)):
#     lane[i] = transformer.transform(*lane[i])


# backend = Data_provider()
# # print("dummy_coord1: ", backend.get_station_score(dummy_coord1, EPSG_4326=False))
# # print("dummy_coord2: ", backend.get_station_score(dummy_coord2))
# # print("dummy_coord3: ", backend.get_station_score(dummy_coord3, EPSG_4326=False))
# print("Line score", backend.line_score(lane, EPSG_4326=False))