Folium 根据值将标记放入标记簇和图层中

问题描述 投票:0回答:2

因此,我正在处理商店数据集,每个商店都有其纬度、经度、名称和类别。 由于我们谈论的是数百甚至数千家商店,因此我正在使用标记集群,并且它们工作正常......

现在,我还需要根据它们的类别将这些商店设置在不同的图层中,这样当我单击“电子商店”时,我只会在地图中获取这些商店(并且它们也应该从标记集群中删除) )

考虑这个示例数据:

stores = [(-23.5578906,-46.6665546, 'store1','electronics'),
             (-23.562711,-46.674363, 'store2','home goods'),
             (-23.5642399,-46.6681833, 'store3','beauty'),
             (-23.584167,-46.678497, 'store4','electronics'),
             (-23.5956238,-46.6865377, 'store5','electronics'),
             (-23.5868682,-46.6773554,'store6','home goods'), 
             (-23.6011096,-46.6739275, 'store7','beauty'),
             (-23.6087354,-46.6973713, 'store8','home goods'),
             (-23.5943515,-46.6846959, 'store9','beauty')]

我的代码可以正常将标记放入群集中,但是当我尝试根据其类别将它们添加到图层时,它不起作用。我没有收到任何错误,并且地图“加载”,但是标记和簇没有显示,并且地图上没有图层。

这是我的代码:

    mymap = folium.Map(location=[y_map, x_map], zoom_start=11,tiles=None)
    folium.TileLayer(name="Mapbox Bright",control=False).add_to(mymap)

    markers_list = []
    all_gp = []
    for lat, lng, name, category zip(df_stores['LAT'], 
                                                  df_stores['LNG'],
                                                  df_stores['NAME'],
                                                  df_stores['CATEGORY']
                                              ):
        html = '''NAME: ''' + name + '''<br>CATEGORY: ''' + category
            
        iframe = folium.IFrame(html,
                               width=300,
                               height=130)

        popup = folium.Popup(iframe,
                                 max_width=300)
        
         
        lead_marker = folium.Marker(
                [lat, lng],   
                popup=popup,
                icon=folium.Icon(color='purple', icon='glyphicon-cutlery', prefix='glyphicon')
        )
        markers_list.append(lead_marker)
        
        pg = category
        all_gp.append(pg)
        
    mCluster = MarkerCluster(name="Stores").add_to(mymap)
    
    for pnt in markers_list:
        pnt.add_to(mCluster)

######################################################################
    # Create point_layer object
    unique_gp = list(set(all_gp))
    vlist = []
    for i,k in enumerate(unique_gp):
        locals()[f'point_layer{i}'] = folium.FeatureGroup(name=k)
        vlist.append(locals()[f'point_layer{i}'])
        
    # Creating list for point_layer
    pl_group = []
    for n in all_gp:
        for v in vlist: 
            if n == vars(v)['layer_name']:
                pl_group.append(v)
                
    for pnt,pg in zip(markers_list,pl_group):
        pnt.add_to(pg)
        pg.add_to(mymap)
######################################################################   
        
    folium.LayerControl().add_to(mymap) 
    mymap.add_child(MeasureControl()) 
    mymap.render()
    mymap.save('stores.html')

############ 行间的代码我在此处采用了另一篇文章(如何将分类分层数据添加到 python Folium 地图中的 LayerControl()?)并将其改编为我的代码,但我似乎错过了一些东西。如果我从代码中取出最后一个 for 循环,地图会正确加载,其集群工作正常,有什么建议吗?

python folium
2个回答
5
投票

我会回答,问题是如何创建类别图层,为属于它的信息添加标记,并使用图层控件控制显示/隐藏。首先,根据数据框中的行信息设置相应的列数据,并添加弹出信息。根据类别信息将类别信息添加到预先准备好的per-category层中。

import pandas as pd
import numpy as np
import folium
from folium.plugins import MarkerCluster

stores = [(-23.5578906,-46.6665546, 'store1','electronics'),
             (-23.562711,-46.674363, 'store2','home goods'),
             (-23.5642399,-46.6681833, 'store3','beauty'),
             (-23.584167,-46.678497, 'store4','electronics'),
             (-23.5956238,-46.6865377, 'store5','electronics'),
             (-23.5868682,-46.6773554,'store6','home goods'), 
             (-23.6011096,-46.6739275, 'store7','beauty'),
             (-23.6087354,-46.6973713, 'store8','home goods'),
             (-23.5943515,-46.6846959, 'store9','beauty')]

df = pd.DataFrame(stores, columns=['LAT','LNG','NAME','CATEGORY'])

mymap = folium.Map(location=[df['LAT'].mean(), df['LNG'].mean()], zoom_start=12)

#mCluster = MarkerCluster(name="Stores").add_to(mymap)
mCluster_hg = MarkerCluster(name="home goods").add_to(mymap)
mCluster_ele = MarkerCluster(name="electronics").add_to(mymap)
mCluster_bea = MarkerCluster(name="beauty").add_to(mymap)

for row in df.itertuples():
    #print(row)
    location = row[1], row[2]
    icon=folium.Icon(color='purple', icon='glyphicon-cutlery', prefix='glyphicon')
    html = '''NAME: ''' + row[3] + '''<br>CATEGORY: ''' + row[4]
    iframe = folium.IFrame(html, width=300, height=130)
    popup = folium.Popup(iframe, max_width=300)
    marker = folium.Marker(location=location, popup=popup, icon=icon)
    #folium.Popup(popup).add_to(marker)
    #mCluster_bea.add_child(marker)
    if row[4] == 'electronics':
        mCluster_ele.add_child(marker)
    elif row[4] == 'home goods':
        mCluster_hg.add_child(marker)
    elif row[4] == 'beauty':
        mCluster_bea.add_child(marker)        

folium.LayerControl().add_to(mymap);

mymap

enter image description here


0
投票

我就是这样做的。如果您有一个新类别,则无需调整代码。基于r-初学者的回答

import pandas as pd
import numpy as np
import folium
from folium.plugins import MarkerCluster

stores = [(-23.5578906,-46.6665546, 'store1','electronics'),
            (-23.562711,-46.674363, 'store2','home goods'),
            (-23.5642399,-46.6681833, 'store3','beauty'),
            (-23.584167,-46.678497, 'store4','electronics'),
            (-23.5956238,-46.6865377, 'store5','electronics'),
            (-23.5868682,-46.6773554,'store6','home goods'), 
            (-23.6011096,-46.6739275, 'store7','beauty'),
            (-23.6087354,-46.6973713, 'store8','home goods'),
            (-23.5943515,-46.6846959, 'store9','beauty')]


df = pd.DataFrame(stores, columns=['LAT','LNG','NAME','CATEGORY'])
layers_to_show = df['CATEGORY'].unique().tolist()

mymap = folium.Map(location=[df['LAT'].mean(), df['LNG'].mean()], zoom_start=12)

marker_cluster=[]
for i,l in enumerate(layers_to_show):
    marker_cluster.append(None)
    df = df_[df_['Layer'] == l]
    for row in df.itertuples():
        location = row[1], row[2]
        icon=folium.Icon(color='purple', icon='glyphicon-cutlery', prefix='glyphicon')
        html = '''NAME: ''' + row[3] + '''<br>CATEGORY: ''' + row[4]
        iframe = folium.IFrame(html, width=300, height=130)
        popup = folium.Popup(iframe, max_width=300).add_to(marker_cluster[i])  
        marker = folium.Marker(location=location, popup=popup, icon=icon).add_to(marker_cluster[i])  
        
folium.LayerControl().add_to(mymap); #maybe this has to be done for every layer

mymap
© www.soinside.com 2019 - 2024. All rights reserved.