Spaces:
Sleeping
Sleeping
Jan
commited on
Commit
·
fccab54
1
Parent(s):
0543051
implement line_score functionality
Browse files
app/data_processing/data_provider.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
from typing import List, Tuple
|
2 |
-
|
3 |
from traitlets import Float
|
4 |
from data_processing.get_smallAreaInfo import get_smallAreas
|
5 |
-
from data_processing.point_scoring import score_current
|
6 |
from data_processing.get_station_coverage import get_station_coverage
|
7 |
from data_processing.aggregate_data import get_feature_df
|
8 |
import os
|
@@ -17,7 +17,7 @@ class Data_provider():
|
|
17 |
self.df = get_feature_df()
|
18 |
self.transformer_to_3057 = Transformer.from_crs("EPSG:4326", "EPSG:3057", always_xy=True)
|
19 |
self.transformer_to_4326 = Transformer.from_crs("EPSG:3057", "EPSG:4326", always_xy=True)
|
20 |
-
|
21 |
|
22 |
|
23 |
def get_station_score(self, station_coord, w_density=1, w_income=1, w_age=1, radius=400, EPSG_4326=True):
|
@@ -83,21 +83,51 @@ class Data_provider():
|
|
83 |
"""
|
84 |
return self.transformer_to_4326.transform(*station_coord)
|
85 |
|
86 |
-
def
|
87 |
-
|
|
|
88 |
for coord in stations_coordinates:
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
from typing import List, Tuple
|
2 |
+
import math
|
3 |
from traitlets import Float
|
4 |
from data_processing.get_smallAreaInfo import get_smallAreas
|
5 |
+
from data_processing.point_scoring import score_current, calc_score_line
|
6 |
from data_processing.get_station_coverage import get_station_coverage
|
7 |
from data_processing.aggregate_data import get_feature_df
|
8 |
import os
|
|
|
17 |
self.df = get_feature_df()
|
18 |
self.transformer_to_3057 = Transformer.from_crs("EPSG:4326", "EPSG:3057", always_xy=True)
|
19 |
self.transformer_to_4326 = Transformer.from_crs("EPSG:3057", "EPSG:4326", always_xy=True)
|
20 |
+
self.PENALTY_SCALE = 100
|
21 |
|
22 |
|
23 |
def get_station_score(self, station_coord, w_density=1, w_income=1, w_age=1, radius=400, EPSG_4326=True):
|
|
|
83 |
"""
|
84 |
return self.transformer_to_4326.transform(*station_coord)
|
85 |
|
86 |
+
def line_score(self, stations_coordinates: List[Tuple[Float]], w_density=1, w_income=1, w_age=1, radius=400, EPSG_4326=True):
|
87 |
+
coords_formatted = []
|
88 |
+
coords_scores = []
|
89 |
for coord in stations_coordinates:
|
90 |
+
coord_formatted = self.__convert_to_3057(coord) if EPSG_4326 else coord
|
91 |
+
coords_formatted.append(coord_formatted)
|
92 |
+
coords_scores.append(self.get_station_score(coord_formatted, w_density, w_income, w_age, radius, EPSG_4326=False))
|
93 |
+
result = calc_score_line(coords_formatted, coords_scores, w_density, w_income, w_age, radius)
|
94 |
+
return result
|
95 |
+
|
96 |
+
|
97 |
+
|
98 |
+
|
99 |
+
# dummy_coord1 = (356250.0, 408250.0) # EPSG:3057 coordinates
|
100 |
+
# dummy_coord2 = (-21.910388, 64.144947) # EPSG:4326 coordinates
|
101 |
+
# dummy_coord3 = (358374.26032876654, 407938.72289760906) # ISN93/Lambert
|
102 |
+
|
103 |
+
# lane = [
|
104 |
+
# (-2427839.8601560914, 9371544.591676729),
|
105 |
+
# (-2431634.4660833703, 9372554.640815599),
|
106 |
+
# (-2434649.232041, 9374913.131190613),
|
107 |
+
# (-2436330.9382214467, 9375856.527340621),
|
108 |
+
# (-2438828.8871577685, 9378030.440208027),
|
109 |
+
# (-2439956.860815385, 9378055.050542375),
|
110 |
+
# (-2442307.1477456186, 9379548.07749282),
|
111 |
+
# (-2441441.6843210473, 9380909.849326741),
|
112 |
+
# (-2441400.6670971345, 9384909.028658295),
|
113 |
+
# (-2441962.6030647475, 9385105.911333079),
|
114 |
+
# (-2443122.365070897, 9385984.705355423),
|
115 |
+
# (-2441898.000937084, 9387355.706064725),
|
116 |
+
# (-2423704.8112703268, 9387223.425517604),
|
117 |
+
# (-2425747.4690212114, 9387959.684686847),
|
118 |
+
# (-2433768.8998727645, 9383004.29132282),
|
119 |
+
# (-2429552.329254474, 9382532.593247818),
|
120 |
+
# (-2436008.4402984325, 9385453.019590447),
|
121 |
+
# (-2438288.9979480137, 9386006.752113278),
|
122 |
+
# (-2439449.7853847607, 9386252.855456758)]
|
123 |
+
|
124 |
+
# transformer = Transformer.from_crs("EPSG:3857", "EPSG:3057", always_xy=True)
|
125 |
+
# for i in range(len(lane)):
|
126 |
+
# lane[i] = transformer.transform(*lane[i])
|
127 |
+
|
128 |
+
|
129 |
+
# backend = Data_provider()
|
130 |
+
# # print("dummy_coord1: ", backend.get_station_score(dummy_coord1, EPSG_4326=False))
|
131 |
+
# # print("dummy_coord2: ", backend.get_station_score(dummy_coord2))
|
132 |
+
# # print("dummy_coord3: ", backend.get_station_score(dummy_coord3, EPSG_4326=False))
|
133 |
+
# print("Line score", backend.line_score(lane, EPSG_4326=False))
|
app/data_processing/point_scoring.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
import csv
|
2 |
import os
|
|
|
|
|
3 |
|
4 |
|
5 |
def score_current(station_coord, df_features, cov_smsv, w_density, w_income, w_age) -> float:
|
@@ -103,7 +105,6 @@ def get_age_score(age_distribution):
|
|
103 |
|
104 |
return weighted_sum / total_population
|
105 |
|
106 |
-
|
107 |
def get_income_score(income_distribution):
|
108 |
"""
|
109 |
Calculate a score based on income distribution.
|
@@ -142,6 +143,54 @@ def get_income_score(income_distribution):
|
|
142 |
|
143 |
return weighted_sum / total_population
|
144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
|
146 |
if __name__ == '__main__':
|
147 |
filename = os.path.join('output.csv')
|
|
|
1 |
import csv
|
2 |
import os
|
3 |
+
from typing import List, Tuple
|
4 |
+
import math
|
5 |
|
6 |
|
7 |
def score_current(station_coord, df_features, cov_smsv, w_density, w_income, w_age) -> float:
|
|
|
105 |
|
106 |
return weighted_sum / total_population
|
107 |
|
|
|
108 |
def get_income_score(income_distribution):
|
109 |
"""
|
110 |
Calculate a score based on income distribution.
|
|
|
143 |
|
144 |
return weighted_sum / total_population
|
145 |
|
146 |
+
def calculate_distance(coord1, coord2):
|
147 |
+
"""Calculate Euclidean distance between two coordinates in EPSG:3057 format."""
|
148 |
+
x1, y1 = coord1
|
149 |
+
x2, y2 = coord2
|
150 |
+
return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
|
151 |
+
|
152 |
+
def calc_score_line(stations_coordinates: List[Tuple[float]], station_scores: dict[str, list[float]], w_density, w_income, w_age, radius):
|
153 |
+
# print("stations_coords1 ", stations_coordinates)
|
154 |
+
PENALTY_SCALE = 1.0
|
155 |
+
individual_total_scores = [station["total_score"] for station in station_scores]
|
156 |
+
overlap_factors = [0] * len(stations_coordinates) # Initialize overlap factors for each station
|
157 |
+
total_penalty = 0
|
158 |
+
|
159 |
+
# Aggregate individual scores
|
160 |
+
total_individual_score = sum(individual_total_scores) / len(individual_total_scores) if individual_total_scores else 0
|
161 |
+
|
162 |
+
# Calculate overlap factors
|
163 |
+
for i, coord1 in enumerate(stations_coordinates):
|
164 |
+
for j, coord2 in enumerate(stations_coordinates):
|
165 |
+
if i != j: # Avoid self-comparison
|
166 |
+
distance = calculate_distance(coord1, coord2)
|
167 |
+
if distance < radius:
|
168 |
+
# Calculate overlap fraction (inverse of distance within the radius)
|
169 |
+
overlap_factor = (radius - distance) / radius # Normalize overlap to [0, 1]
|
170 |
+
overlap_factors[i] += overlap_factor
|
171 |
+
overlap_factors[j] += overlap_factor
|
172 |
+
|
173 |
+
# Scale down individual scores based on overlap factors
|
174 |
+
adjusted_scores = [
|
175 |
+
max(0, score * (1 - PENALTY_SCALE * min(1, overlap_factors[i]))) # Cap scaling at 100%
|
176 |
+
for i, score in enumerate(individual_total_scores)
|
177 |
+
]
|
178 |
+
|
179 |
+
# Final aggregated score
|
180 |
+
final_score = sum(adjusted_scores) / len(adjusted_scores) if adjusted_scores else 0
|
181 |
+
|
182 |
+
# Return detailed results
|
183 |
+
result = {
|
184 |
+
"individual_scores": individual_total_scores,
|
185 |
+
"adjusted_scores": adjusted_scores,
|
186 |
+
"overlap_factors": overlap_factors,
|
187 |
+
"total_individual_score": total_individual_score,
|
188 |
+
"final_score": final_score
|
189 |
+
}
|
190 |
+
return result
|
191 |
+
|
192 |
+
|
193 |
+
|
194 |
|
195 |
if __name__ == '__main__':
|
196 |
filename = os.path.join('output.csv')
|