[1]:
import geopandas as gpd

blocks_land_use_gdf = gpd.read_file('./../data/blocks.geojson')[['geometry']]
crs = blocks_land_use_gdf.estimate_utm_crs()
blocks_land_use_gdf = blocks_land_use_gdf.to_crs(crs)
blocks_land_use_gdf['land_use'] = None
blocks_land_use_gdf.head()
[1]:
geometry land_use
0 POLYGON ((387861.999 6644712.938, 387898.372 6... None
1 POLYGON ((387898.372 6644768.891, 387934.746 6... None
2 POLYGON ((387934.746 6644824.845, 388202.551 6... None
3 POLYGON ((388348.842 6645181.924, 388955.181 6... None
4 POLYGON ((388955.181 6644954.448, 389507.545 6... None
[2]:
from blocksnet.preprocessing.feature_engineering import generate_geometry_features

blocks_features_gdf = generate_geometry_features(blocks_land_use_gdf, aspect_ratios=True)
blocks_features_gdf.head()
2025-03-23 01:28:59.914 | INFO     | blocksnet.preprocessing.feature_engineering.core:_calculate_usual_features:34 - Calculating usual features.
2025-03-23 01:28:59.918 | INFO     | blocksnet.preprocessing.feature_engineering.core:_calculate_aspect_ratios:57 - Calculating radiuses.
100%|██████████| 69/69 [00:00<00:00, 29165.27it/s]
[2]:
geometry x y area length corners_count aspect_ratio
0 POLYGON ((387861.999 6644712.938, 387898.372 6... 387811.257163 6.644418e+06 109189.559722 1790.182603 6 3.186357
1 POLYGON ((387898.372 6644768.891, 387934.746 6... 387931.811285 6.644396e+06 72838.889774 1626.063797 5 3.918795
2 POLYGON ((387934.746 6644824.845, 388202.551 6... 388230.122121 6.645052e+06 134496.100428 1480.126322 6 1.554021
3 POLYGON ((388348.842 6645181.924, 388955.181 6... 388513.077158 6.645068e+06 108999.835249 1546.823257 5 2.908831
4 POLYGON ((388955.181 6644954.448, 389507.545 6... 389371.433283 6.644714e+06 164356.406931 2197.983249 6 4.324339
[3]:
blocks_gdf = blocks_features_gdf.join(blocks_land_use_gdf[['land_use']])
blocks_gdf.head()
[3]:
geometry x y area length corners_count aspect_ratio land_use
0 POLYGON ((387861.999 6644712.938, 387898.372 6... 387811.257163 6.644418e+06 109189.559722 1790.182603 6 3.186357 None
1 POLYGON ((387898.372 6644768.891, 387934.746 6... 387931.811285 6.644396e+06 72838.889774 1626.063797 5 3.918795 None
2 POLYGON ((387934.746 6644824.845, 388202.551 6... 388230.122121 6.645052e+06 134496.100428 1480.126322 6 1.554021 None
3 POLYGON ((388348.842 6645181.924, 388955.181 6... 388513.077158 6.645068e+06 108999.835249 1546.823257 5 2.908831 None
4 POLYGON ((388955.181 6644954.448, 389507.545 6... 389371.433283 6.644714e+06 164356.406931 2197.983249 6 4.324339 None
[4]:
from blocksnet.relations import generate_adjacency_graph, get_adjacency_context

adjacency_graph = generate_adjacency_graph(blocks_land_use_gdf)
2025-03-23 01:28:59.967 | INFO     | blocksnet.relations.adjacency.core:_generate_adjacency_nodes:10 - Generating nodes.
2025-03-23 01:28:59.968 | INFO     | blocksnet.relations.adjacency.core:_generate_adjacency_edges:15 - Generating edges.
2025-03-23 01:29:00.122 | SUCCESS  | blocksnet.relations.adjacency.core:generate_adjacency_graph:34 - Adjacency graph successfully generated: 69 nodes, 68 edges

Optimization

[5]:
from blocksnet.enums import LandUse

target_shares = {
    LandUse.RESIDENTIAL : 0.5,
    LandUse.RECREATION : 0.3,
    LandUse.BUSINESS : 0.2
}

blocks_ids = list(blocks_gdf.index)
[6]:
from blocksnet.optimization.land_use import LandUseOptimizer

luo = LandUseOptimizer(blocks_gdf, adjacency_graph)
res_df = luo.run(blocks_ids, target_shares, population_size=10, n_generations=100, mutation_probability=0.5)
==========================================================
n_gen  |  n_eval  | n_nds  |      eps      |   indicator
==========================================================
     1 |       10 |      4 |             - |             -
     2 |       20 |      5 |  0.0914873395 |             f
     3 |       30 |      7 |  0.1144523497 |         ideal
     4 |       40 |     10 |  0.0781781516 |         ideal
     5 |       50 |      9 |  0.0697504645 |         ideal
     6 |       60 |      6 |  0.0922243946 |             f
     7 |       70 |      7 |  0.1150895082 |         ideal
     8 |       80 |      7 |  0.2086888225 |         ideal
     9 |       90 |      8 |  0.0362955085 |             f
    10 |      100 |      8 |  0.000000E+00 |             f
    11 |      110 |      7 |  0.0362269873 |             f
    12 |      120 |      7 |  0.000000E+00 |             f
    13 |      130 |      8 |  0.0159126744 |             f
    14 |      140 |      8 |  0.000000E+00 |             f
    15 |      150 |      8 |  0.000000E+00 |             f
    16 |      160 |      9 |  0.0477094116 |         ideal
    17 |      170 |      9 |  0.000000E+00 |             f
    18 |      180 |      9 |  0.000000E+00 |             f
    19 |      190 |      9 |  0.0050881715 |             f
    20 |      200 |     10 |  0.0034969770 |             f
    21 |      210 |     10 |  0.000000E+00 |             f
    22 |      220 |     10 |  0.0014155321 |             f
    23 |      230 |     10 |  0.0064667153 |             f
    24 |      240 |     10 |  0.000000E+00 |             f
    25 |      250 |      8 |  0.0400332670 |             f
    26 |      260 |      9 |  0.0084712670 |             f
    27 |      270 |     10 |  0.0846586509 |         ideal
    28 |      280 |     10 |  0.000000E+00 |             f
    29 |      290 |     10 |  0.000000E+00 |             f
    30 |      300 |      9 |  0.0121405555 |             f
    31 |      310 |      9 |  0.000000E+00 |             f
    32 |      320 |      9 |  0.0017296025 |             f
    33 |      330 |      9 |  0.0017296025 |             f
    34 |      340 |      9 |  0.0017296025 |             f
    35 |      350 |      9 |  0.0017296025 |             f
    36 |      360 |      9 |  0.0017296025 |             f
    37 |      370 |      9 |  0.0017296025 |             f
    38 |      380 |      8 |  0.0286007670 |             f
    39 |      390 |      8 |  0.000000E+00 |             f
    40 |      400 |      8 |  0.000000E+00 |             f
    41 |      410 |      8 |  0.000000E+00 |             f
    42 |      420 |      8 |  0.000000E+00 |             f
    43 |      430 |      8 |  0.000000E+00 |             f
    44 |      440 |      9 |  0.0289729798 |             f
    45 |      450 |     10 |  0.0104330004 |             f
    46 |      460 |     10 |  0.000000E+00 |             f
    47 |      470 |     10 |  0.000000E+00 |             f
    48 |      480 |     10 |  0.000000E+00 |             f
    49 |      490 |     10 |  0.000000E+00 |             f
    50 |      500 |     10 |  0.0113978961 |             f
    51 |      510 |      8 |  0.0103157549 |             f
    52 |      520 |      8 |  0.000000E+00 |             f
    53 |      530 |      8 |  0.000000E+00 |             f
    54 |      540 |      8 |  0.000000E+00 |             f
    55 |      550 |      8 |  0.000000E+00 |             f
    56 |      560 |      8 |  0.000000E+00 |             f
    57 |      570 |      6 |  0.0060698124 |         ideal
    58 |      580 |      6 |  0.000000E+00 |             f
    59 |      590 |      6 |  0.000000E+00 |             f
    60 |      600 |      6 |  0.000000E+00 |             f
    61 |      610 |      6 |  0.000000E+00 |             f
    62 |      620 |      7 |  0.0107661662 |             f
    63 |      630 |      7 |  0.000000E+00 |             f
    64 |      640 |      8 |  0.0147008371 |             f
    65 |      650 |      8 |  0.000000E+00 |             f
    66 |      660 |      8 |  0.000000E+00 |             f
    67 |      670 |      8 |  0.000000E+00 |             f
    68 |      680 |      9 |  0.0214649602 |             f
    69 |      690 |      9 |  0.000000E+00 |             f
    70 |      700 |      9 |  0.000000E+00 |             f
    71 |      710 |      9 |  0.000000E+00 |             f
    72 |      720 |      9 |  0.000000E+00 |             f
    73 |      730 |      9 |  0.000000E+00 |             f
    74 |      740 |      9 |  0.000000E+00 |             f
    75 |      750 |      7 |  0.0263487296 |         ideal
    76 |      760 |      8 |  0.0844521501 |         ideal
    77 |      770 |      8 |  0.000000E+00 |             f
    78 |      780 |      9 |  0.0077841329 |             f
    79 |      790 |      9 |  0.000000E+00 |             f
    80 |      800 |     10 |  0.0082204478 |             f
    81 |      810 |     10 |  0.0073915551 |             f
    82 |      820 |     10 |  0.000000E+00 |             f
    83 |      830 |     10 |  0.000000E+00 |             f
    84 |      840 |     10 |  0.000000E+00 |             f
    85 |      850 |     10 |  0.000000E+00 |             f
    86 |      860 |     10 |  0.000000E+00 |             f
    87 |      870 |     10 |  0.000000E+00 |             f
    88 |      880 |     10 |  0.000000E+00 |             f
    89 |      890 |     10 |  0.000000E+00 |             f
    90 |      900 |     10 |  0.000000E+00 |             f
    91 |      910 |     10 |  0.000000E+00 |             f
    92 |      920 |     10 |  0.000000E+00 |             f
    93 |      930 |     10 |  0.0059969017 |             f
    94 |      940 |     10 |  0.000000E+00 |             f
    95 |      950 |     10 |  0.000000E+00 |             f
    96 |      960 |     10 |  0.000000E+00 |             f
    97 |      970 |     10 |  0.0546159771 |         ideal
    98 |      980 |     10 |  0.000000E+00 |             f
    99 |      990 |     10 |  0.0063171357 |             f
   100 |     1000 |     10 |  0.000000E+00 |             f
[7]:
res_df
[7]:
solution objectives assigned_land_use share_mse adjacency_penalty
0 [3, 4, 2, 1, 2, 0, 0, 1, 0, 0, 3, 0, 0, 3, 3, ... [0.035492561216084254, 0.2593212019104734] {0: LandUse.INDUSTRIAL, 1: LandUse.TRANSPORT, ... 0.035493 0.259321
1 [2, 4, 4, 0, 2, 0, 0, 1, 3, 1, 0, 0, 4, 3, 1, ... [0.044256914631729864, 0.1661670812536721] {0: LandUse.RECREATION, 1: LandUse.TRANSPORT, ... 0.044257 0.166167
2 [2, 4, 2, 2, 2, 0, 2, 1, 0, 4, 2, 4, 1, 4, 3, ... [0.05263684384744122, 0.15835383334955214] {0: LandUse.RECREATION, 1: LandUse.TRANSPORT, ... 0.052637 0.158354
3 [6, 4, 4, 0, 2, 0, 0, 0, 2, 1, 0, 6, 2, 0, 2, ... [0.05854662600284991, 0.1255095223473388] {0: LandUse.AGRICULTURE, 1: LandUse.TRANSPORT,... 0.058547 0.125510
4 [0, 0, 4, 4, 2, 0, 2, 6, 3, 4, 0, 0, 0, 0, 3, ... [0.06213043548928794, 0.1067124990352423] {0: LandUse.RESIDENTIAL, 1: LandUse.RESIDENTIA... 0.062130 0.106712
5 [1, 5, 3, 4, 1, 2, 2, 0, 1, 4, 1, 5, 0, 0, 3, ... [0.06700588458395144, 0.07113174003059475] {0: LandUse.BUSINESS, 1: LandUse.SPECIAL, 2: L... 0.067006 0.071132
6 [2, 4, 4, 4, 2, 0, 2, 0, 2, 1, 0, 5, 2, 0, 4, ... [0.079948146612734, 0.05258978176273955] {0: LandUse.RECREATION, 1: LandUse.TRANSPORT, ... 0.079948 0.052590
7 [3, 2, 2, 3, 2, 0, 2, 2, 0, 3, 1, 5, 0, 6, 3, ... [0.08925728380062802, 0.038751514097945805] {0: LandUse.INDUSTRIAL, 1: LandUse.RECREATION,... 0.089257 0.038752
8 [5, 6, 4, 5, 2, 0, 2, 2, 3, 0, 2, 1, 6, 4, 3, ... [0.13927148694530989, 0.02508436674300687] {0: LandUse.SPECIAL, 1: LandUse.AGRICULTURE, 2... 0.139271 0.025084
9 [3, 2, 4, 1, 2, 3, 2, 0, 1, 0, 2, 1, 1, 4, 3, ... [0.17998316331805234, 0.01155222181087819] {0: LandUse.INDUSTRIAL, 1: LandUse.RECREATION,... 0.179983 0.011552