2222 LandUse .RECREATION : 0.05 ,
2323}
2424DEFAULT_LU_CONST = 0.06
25+
26+ LU_TRIP_RATES = {
27+ LandUse .RESIDENTIAL : 1.0 ,
28+ LandUse .BUSINESS : 2.7 ,
29+ LandUse .INDUSTRIAL : 2.0 ,
30+ LandUse .SPECIAL : 1.2 ,
31+ LandUse .TRANSPORT : 1.0 ,
32+ LandUse .RECREATION : 1.4 ,
33+ LandUse .AGRICULTURE : 0.2 ,
34+ }
35+ DEFAULT_TRIP_RATE = 1.0
36+
2537DEFAULT_ACCESSIBILITY = 10
2638
2739
@@ -68,7 +80,12 @@ def _integerize_origin_constrained_od(od_prob_mx: pd.DataFrame, demand: pd.Serie
6880 return od_int
6981
7082
71- def _calculate_nodes_weights (blocks_df : gpd .GeoDataFrame , acc_mx : pd .DataFrame , accessibility : float ) -> pd .DataFrame :
83+ def _calculate_nodes_weights (
84+ blocks_df : gpd .GeoDataFrame ,
85+ acc_mx : pd .DataFrame ,
86+ accessibility : float ,
87+ trip_rates : dict [LandUse , float ],
88+ ) -> pd .DataFrame :
7289
7390 logger .info ("Identifying nearest nodes to blocks" )
7491 acc_mx = acc_mx .replace (0 , 0.1 )
@@ -81,10 +98,14 @@ def _calculate_nodes_weights(blocks_df: gpd.GeoDataFrame, acc_mx: pd.DataFrame,
8198 weights_sum = weights_mx .sum (axis = 1 )
8299 weights_mx = weights_mx .div (weights_sum , axis = 0 )
83100
101+ effective_population = blocks_df [POPULATION_COLUMN ] * blocks_df .land_use .map (
102+ lambda lu : trip_rates .get (lu , DEFAULT_TRIP_RATE )
103+ )
104+
84105 logger .info ("Distributing" )
85106 nodes_df = pd .DataFrame (index = acc_mx .columns )
86107 nodes_df [ATTRACTIVENESS_COLUMN ] = weights_mx .mul (blocks_df [ATTRACTIVENESS_COLUMN ], axis = 0 ).sum (axis = 0 )
87- nodes_df [POPULATION_COLUMN ] = weights_mx .mul (blocks_df [ POPULATION_COLUMN ] , axis = 0 ).sum (axis = 0 )
108+ nodes_df [POPULATION_COLUMN ] = weights_mx .mul (effective_population , axis = 0 ).sum (axis = 0 )
88109 return nodes_df
89110
90111
@@ -99,10 +120,10 @@ def _calculate_diversity(blocks_df: pd.DataFrame, services_count_dfs: list[pd.Da
99120def _calculate_attractiveness (blocks_df : pd .DataFrame , lu_consts : dict [LandUse , float ]) -> pd .DataFrame :
100121 logger .info ("Calculating attractiveness" )
101122 blocks_df = blocks_df .copy ()
123+ blocks_df [LU_CONST_COLUMN ] = blocks_df .land_use .apply (lambda lu : lu_consts .get (lu , DEFAULT_LU_CONST ))
102124 scaler = MinMaxScaler ()
103- columns = [DENSITY_COLUMN , SHANNON_DIVERSITY_COLUMN ]
125+ columns = [DENSITY_COLUMN , SHANNON_DIVERSITY_COLUMN , LU_CONST_COLUMN ]
104126 blocks_df [columns ] = scaler .fit_transform (blocks_df [columns ])
105- blocks_df [LU_CONST_COLUMN ] = blocks_df .land_use .apply (lambda lu : lu_consts .get (lu , DEFAULT_LU_CONST ))
106127 blocks_df [ATTRACTIVENESS_COLUMN ] = (
107128 blocks_df [DENSITY_COLUMN ] + blocks_df [SHANNON_DIVERSITY_COLUMN ] + blocks_df [LU_CONST_COLUMN ]
108129 )
@@ -145,6 +166,7 @@ def origin_destination_matrix(
145166 services_count_dfs : list [pd .DataFrame ],
146167 accessibility : float = DEFAULT_ACCESSIBILITY ,
147168 lu_consts : dict [LandUse , float ] = LU_CONSTS ,
169+ lu_trip_rates : dict [LandUse , float ] = LU_TRIP_RATES ,
148170) -> pd .DataFrame :
149171
150172 """
@@ -229,6 +251,6 @@ def origin_destination_matrix(
229251 blocks_df = _calculate_diversity (blocks_df , services_count_dfs )
230252 blocks_df = _calculate_attractiveness (blocks_df , lu_consts )
231253
232- nodes_gdf = _calculate_nodes_weights (blocks_df , blocks_to_nodes_mx , accessibility )
254+ nodes_gdf = _calculate_nodes_weights (blocks_df , blocks_to_nodes_mx , accessibility , lu_trip_rates )
233255
234256 return _calculate_od_mx (nodes_gdf , nodes_to_nodes_mx )
0 commit comments