# HIDDEN
import ipywidgets as widgets
from ipywidgets import interact, interact_manual
import osmnx as ox
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import matplotlib as mpl
import string
import numpy as np
# HIDDEN
def draw_map(Address,Distance,Netwerk_input,bg_color):
    # Define two arrays for streetnames and colours that you want to give these streettypes. Put the 'other' label and colour at the end
    names=['straat','weg','steeg','laan','erf','hof','gracht','kade','dreef','plein','burg','burcht','pad','lei','steijn','other']
    colours=['red','gainsboro', 'purple','green', 'springgreen','darkgreen','blue','deepskyblue','plum','fuchsia','peru','saddlebrown','burlywood','dimgray','rosybrown','grey']
    
    #Create patches for all the names, colours combinations
    patch_array = []
    for i,items in enumerate(names):
        patch_array.append(mpatches.Patch(color=colours[i],label=names[i]))
    
    #Create an array that can be multiplied later to create a correct legend
    patch_factors= [0] * len(names)
    
    # Give each streettype a color based on the name. If both names occur (eg: Rijksstraatweg), last one in the list wins
    # If the street is the input street it gets a separate colour. If it's not one of the listed street=types, it get's the colour belonging to other
    def what_colour(x):
        for i, items in enumerate(names):
            if x==your_street: return '#ff6200'
            elif (items in x): 
                patch_factors[i]=1
                return colours[i]
        #first finish the whole names array, if it's not in there, return the 'other' color
        else: 
            patch_factors[int(len(patch_factors))-1]=1
            return colours[int(len(patch_factors))-1]
        
    # Give the input street a wider linewidth
    def linethick(x):
        if x==your_street: return 7
        else: return 1
   
    # USE THE USER INPUT TO CREATE A GRAPH AROUND THAT ADDRESS
    G3 = ox.graph_from_address(Address, network_type=Netwerk_input,dist=Distance, dist_type='bbox', simplify=False)
    edge_attributes = ox.graph_to_gdfs(G3, nodes=False)
        
    #Split the entered address into street and city
    your_street=Address.split(',',1)[0].lower()
    city=Address.split(',',1)[1].lower().strip()
        
    #populate colors and linewidth
    ec = [what_colour(str(row['name']).lower()) for index, row in edge_attributes.iterrows()]
    lw = [linethick(str(row['name']).lower()) for index, row in edge_attributes.iterrows()]
    fig,ax= ox.plot.plot_graph(G3, ax=None, figsize=(25,25), bgcolor=bg_color, node_size=0, node_color='w', node_edgecolor='gray', node_zorder=2,
                        edge_color=ec, edge_linewidth=lw, edge_alpha=1,  dpi=300 , show=False, close=False)
    # ADD TITLE AND LEGEND
    #Add a rectangle to give the title and legend a solid background
    fig.patches.extend([plt.Rectangle((0.1,0.1),0.83,0.9,
                                  fill=True, color=bg_color, alpha=1, zorder=-1,
                                  transform=fig.transFigure, figure=fig)])
    #Add titles
    if bg_color == 'black':
        fontcolor='white'
    else:
        fontcolor='black'
    plt.figtext(0.5, 0.94,string.capwords(your_street), fontsize=40, color='#ff6200', ha ='center')
    plt.figtext(0.5, 0.97,string.capwords(city), fontsize=40, color=fontcolor, ha ='center')
    
    #Create patches for the legend
    your_street_patch=mpatches.Patch(color='#ff6200', label='Jouw straat')
    
    #create your street legend
    first_legend=plt.legend(fontsize=24,labelcolor=fontcolor, frameon=False, bbox_to_anchor=(0.5, 1.08), loc='upper center',handles=[your_street_patch])
    # Add the legend manually to the current Axes.
    ax = plt.gca().add_artist(first_legend)
    
    # Create another legend for the rest
    #use the patch_factors to only append the patches that need to be in the legend
    legend_array= []
    for i,factors in enumerate(patch_factors):
        if factors==1:
            legend_array.append(mpatches.Patch(color=colours[i],label=names[i]))
    
    #Create the correct number of columns for the legend so that there are always two rows.
    if (len(legend_array) % 2) == 0:
        cols=int(len(legend_array)/2) 
    else: 
        cols=int(len(legend_array)/2)+1
        
    plt.legend(fontsize=20,labelcolor=fontcolor, frameon=False,loc='upper center', bbox_to_anchor=(0.5, 1.05), ncol=cols, handles=legend_array)
    
    plt.show()
# HIDDEN
im=interact_manual(draw_map,
                   Address='Dam, Amsterdam',
                   Distance=widgets.IntSlider(min=500, max=5000, step=500),
                   Netwerk_input=['drive','bike','walk','all'],
                   bg_color=['black','white']
                   )
# Layout makes it possible to set width and heigth for a widget
# Style makes it possible to give the description a wider box
layout = widgets.Layout(width='auto') #set width and height
style = {'description_width': 'initial'}

im.widget.children[0].description = 'Je adres (straatnaam, plaatsnaam)'
im.widget.children[0].style=style
im.widget.children[0].layout=layout
im.widget.children[1].description = 'Afstand (in meters)'
im.widget.children[1].style=style
im.widget.children[1].layout=layout
im.widget.children[2].description = 'Type netwerk (alleen autowegen, of ook wandelpaden)'
im.widget.children[2].style=style
im.widget.children[2].layout=layout
im.widget.children[3].description = 'Kies achtergrondkleur'
im.widget.children[3].style=style
im.widget.children[3].layout=layout

im.widget.children[4].description = 'Maak een kaartje!'
display(im)
<function __main__.draw_map(Address, Distance, Netwerk_input, bg_color)>