Python – Fixing Error ‘NoneType Object is Not Subscriptable’ in Folium

foliumpython

Since days and days, I could not figure out this issue. I got this error

'NoneType' object is not subscriptable. 
lib/python3.8/site-packages/folium/features.py

The problem is at this point:

layer=folium.GeoJson(
            edges_gdf,
            tooltip=folium.GeoJsonTooltip(fields=['oneway','lanes',
            'length','speed','name'],localize=True),
            style_function=lambda x: {'color': line_color}).add_to(m)

Here is the full function:

def retrieve_data_from_postgres(network_id, Simple,
                          set_initial_crs=4326,
                          zone_radius=15,
                          intersection_radius_percentage=0.8,
                          distance_offset_percentage=0.8,
                          line_color='orange',
                          link_side='right',

                          ):
    initial_crs = "EPSG:{}".format(set_initial_crs)
    initial_crs = CRS(initial_crs)
    CRS84 = "EPSG:4326"
    default_crs = "EPSG:3857"

    edges = Edge.objects.filter(network_id=network_id)
    edges = serialize('geojson', edges,
        fields=('id', 'param1', 'param2', 'param3', 'speed', 'length',
        'lanes','geometry', 'name', 'source', 'target','network', 'road_type'))

    edges = json.loads(edges)
    edges_gdf = gpd.GeoDataFrame.from_features(edges['features']) 

    nodes = Node.objects.filter(network_id=network_id).values()
    nodes_df = pd.DataFrame(nodes)
    nodes_df['location'] = nodes_df['location'].apply(geometry.Point)
    nodes_gdf = gpd.GeoDataFrame(nodes_df, geometry=nodes_df['location'])

    edges_gdf.set_crs(initial_crs, inplace=True)
    nodes_gdf.set_crs(initial_crs, inplace=True)
    nodes_gdf.to_crs(CRS84, inplace=True)
    zone_radius = zone_radius
    intersection_radius = intersection_radius_percentage * zone_radius
    distance_offset = distance_offset_percentage * zone_radius
    tiles_layer = 'OpenStreetMap'

    edges_gdf["oneway"] = edges_gdf.apply(lambda x: not edges_gdf[
        (edges_gdf["source"] == x["target"]) & (edges_gdf["target"] == x["source"])
        ].empty, axis=1)

    edges_gdf.to_crs(crs=default_crs, inplace=True)

    col_list = ['geometry', 'oneway']
    edges_gdf['_offset_geometry_'] = edges_gdf[col_list].apply(
        lambda x: x['geometry'].parallel_offset(distance_offset, link_side) if not x['oneway']
        else x['geometry'].parallel_offset(0, link_side),axis=1)


    edges_gdf.drop('geometry', axis=1, inplace=True)
    edges_gdf.set_geometry('_offset_geometry_', inplace=True)
    edges_gdf.set_crs(default_crs, inplace=True)
    edges_gdf.to_crs(crs=CRS84, inplace=True)

    latitudes = list(nodes_gdf['geometry'].y)
    longitudes = list(nodes_gdf['geometry'].x)

    # Initialize the map
    m = folium.Map(location=[latitudes[0], longitudes[0]],
                   max_zoom=18, prefer_canvas=True, tiles=tiles_layer)

    layer=folium.GeoJson(
        edges_gdf,
        tooltip=folium.GeoJsonTooltip(fields=['oneway','lanes',
        'length','speed','name'],localize=True),
        style_function=lambda x: {'color': line_color}).add_to(m)
    m.fit_bounds(layer.get_bounds())

    # Adding the nodes points
    for lat, long in list(zip(latitudes, longitudes)):
        folium.Circle(location=[lat, long], color='cyan', fill=True,
            fill_opacity=1,radius=intersection_radius).add_to(m)

    m.save('templates/visualization.html')

Best Answer

latitudes = list(nodes_gdf['geometry'].y)
longitudes = list(nodes_gdf['geometry'].x)

# Initialize the map
m = folium.Map(location=[latitudes[0], longitudes[0]],
               max_zoom=18, prefer_canvas=True, tiles=tiles_layer)

layer=folium.GeoJson(
    edges_gdf,
    tooltip=folium.GeoJsonTooltip(fields=['oneway','lanes',
    'length','speed','name'],localize=True),
    style_function=lambda x: {'color': line_color}).add_to(m)
m.fit_bounds(layer.get_bounds())

The error message is saying that you tried to use a None object as a list (or array), so the problem is unlikely to be on that line but above it somewhere. I would guess it is the line that creates the Map and that either latitudes or longitudes (or both) are None for one of your geometries, which might be related to:

edges_gdf.drop('geometry', axis=1, inplace=True)