@@ -1487,7 +1487,14 @@ def cumulative_curves(s, links=None, figsize=(6,4)):
14871487 plt .show ()
14881488 else :
14891489 plt .close ("all" )
1490-
1490+
1491+ def import_contextily (s ):
1492+ try :
1493+ import contextily as ctx
1494+ return ctx
1495+ except ImportError :
1496+ raise ImportError ("contextily must be installed to use the basemap feature." )
1497+
14911498 @catch_exceptions_and_warn ()
14921499 def network (s , t = None , detailed = 1 , minwidth = 0.5 , maxwidth = 12 , left_handed = 1 , tmp_anim = 0 , figsize = (6 ,6 ), network_font_size = 4 , node_size = 2 ):
14931500 """
@@ -1594,7 +1601,7 @@ def network(s, t=None, detailed=1, minwidth=0.5, maxwidth=12, left_handed=1, tmp
15941601 plt .close ("all" )
15951602
15961603 @catch_exceptions_and_warn ()
1597- def network_pillow (s , t = None , detailed = 1 , minwidth = 0.5 , maxwidth = 12 , left_handed = 1 , tmp_anim = 0 , figsize = 6 , network_font_size = 20 , node_size = 2 , image_return = 0 ):
1604+ def network_pillow (s , t = None , detailed = 1 , minwidth = 0.5 , maxwidth = 12 , left_handed = 1 , tmp_anim = 0 , figsize = 6 , network_font_size = 20 , node_size = 2 , basemap = None , image_return = 0 ):
15981605 """
15991606 Visualizes the entire transportation network and its current traffic conditions. Faster implementation using Pillow.
16001607
@@ -1620,6 +1627,9 @@ def network_pillow(s, t=None, detailed=1, minwidth=0.5, maxwidth=12, left_handed
16201627 The font size for the network labels. Default is 4.
16211628 node_size : int, optional
16221629 The size of the nodes in the visualization. Default is 2.
1630+ basemap : Contextily provider object, optional
1631+ The basemap provider to be used for the visualization. Default is None.
1632+ See https://contextily.readthedocs.io/en/latest/providers_deepdive.html
16231633
16241634 Notes
16251635 -----
@@ -1685,6 +1695,16 @@ def flip(y):
16851695 font = ImageFont .truetype (font_fname , int (30 ))
16861696 draw .text ((img .size [0 ]/ 2 ,20 ), f"t = { t :>8} (s)" , font = font , fill = "black" , anchor = "mm" )
16871697
1698+ # Add a basemap with contextily
1699+ if basemap is not None :
1700+ ctx = s .import_contextily ()
1701+ # Adjust bounds to the format expected by contextily (west, south, east, north)
1702+ bounds_ctx = [minx , miny , maxx , maxy ]
1703+ # Fetch the basemap
1704+ basemap_img , basemap_extent = ctx .bounds2img (* bounds_ctx , zoom = 'auto' , source = basemap )
1705+ # Overlay the network visualization on the basemap
1706+ img = Image .alpha_composite (Image .fromarray (basemap_img ), img )
1707+
16881708 img = img .resize ((int ((maxx - minx )/ scale ), int ((maxy - miny )/ scale )), resample = Resampling .LANCZOS )
16891709 if image_return :
16901710 return img
@@ -1712,7 +1732,7 @@ def show_simulation_progress(s):
17121732 print (f"{ s .W .TIME :>8.0f} s| { sum_vehs :>8.0f} vehs| { avev :>4.1f} m/s| { time .time ()- s .W .sim_start_time :8.2f} s" , flush = True )
17131733
17141734 @catch_exceptions_and_warn ()
1715- def network_anim (s , animation_speed_inverse = 10 , detailed = 0 , minwidth = 0.5 , maxwidth = 12 , left_handed = 1 , figsize = (6 ,6 ), node_size = 2 , network_font_size = 20 , timestep_skip = 24 ):
1735+ def network_anim (s , animation_speed_inverse = 10 , detailed = 0 , minwidth = 0.5 , maxwidth = 12 , left_handed = 1 , figsize = (6 ,6 ), node_size = 2 , network_font_size = 20 , timestep_skip = 24 , basemap = None ):
17161736 """
17171737 Generates an animation of the entire transportation network and its traffic states over time.
17181738
@@ -1739,6 +1759,9 @@ def network_anim(s, animation_speed_inverse=10, detailed=0, minwidth=0.5, maxwid
17391759 The font size for the network labels in the animation. Default is 20.
17401760 timestep_skip : int, optional
17411761 How many timesteps are skipped per frame. Large value means coarse and lightweight animation. Default is 8.
1762+ basemap : Contextily provider object, optional
1763+ The basemap provider to be used for the visualization. Default is None.
1764+ See https://contextily.readthedocs.io/en/latest/providers_deepdive.html
17421765
17431766 Notes
17441767 -----
@@ -1756,7 +1779,7 @@ def network_anim(s, animation_speed_inverse=10, detailed=0, minwidth=0.5, maxwid
17561779 #todo_later: 今後はこちらもpillowにする
17571780 s .network (int (t ), detailed = detailed , minwidth = minwidth , maxwidth = maxwidth , left_handed = left_handed , tmp_anim = 1 , figsize = figsize , node_size = node_size , network_font_size = network_font_size )
17581781 else :
1759- s .network_pillow (int (t ), detailed = detailed , minwidth = minwidth , maxwidth = maxwidth , left_handed = left_handed , tmp_anim = 1 , figsize = figsize , node_size = node_size , network_font_size = network_font_size )
1782+ s .network_pillow (int (t ), detailed = detailed , minwidth = minwidth , maxwidth = maxwidth , left_handed = left_handed , tmp_anim = 1 , figsize = figsize , node_size = node_size , network_font_size = network_font_size , basemap = basemap )
17601783 pics .append (Image .open (f"out{ s .W .name } /tmp_anim_{ t } .png" ))
17611784 pics [0 ].save (f"out{ s .W .name } /anim_network{ detailed } .gif" , save_all = True , append_images = pics [1 :], optimize = False , duration = animation_speed_inverse * timestep_skip , loop = 0 )
17621785 for f in glob .glob (f"out{ s .W .name } /tmp_anim_*.png" ):
0 commit comments