【Python】Folium:调用Leaflet交互地图

创建基础地图与地图样式

Folium 是一个功能强大的 Python 库,可以轻松创建交互式地图。在这部分,我们将学习如何创建基础地图以及如何设置不同的地图样式,包括使用自定义地图服务。

创建基础地图

使用 folium.Map() 创建基础地图。你可以指定地图的初始位置和缩放级别。

# 创建地图对象,默认使用 OpenStreetMap 样式
m = folium.Map(location=[39.9, 116.4], zoom_start=10)
  • location: 地图中心的经纬度,格式为 [纬度, 经度]
  • zoom_start: 地图初始缩放级别,范围通常为 1 到 18,数值越大,地图越详细。
  • 设置不同地图样式

    Folium 支持多种地图样式,可以通过 tiles 参数轻松切换。以下是一些常用地图样式的对照表:

    地图样式 描述 备注
    OpenStreetMap 默认样式 开源地图,常用于基础地图
    Stamen Terrain 地形图样式 提供详细的地形信息
    Stamen Toner 高对比度黑白地图样式 适合打印或高对比度场景
    Stamen Watercolor 水彩风格地图样式 具有艺术感的地图视觉效果
    CartoDB positron 现代、干净的地图样式 适合可视化和展示数据
    CartoDB dark_matter 黑色主题地图样式 适合夜间模式或暗色主题
    Mapbox 高级自定义地图样式 需提供 API 密钥

    使用这些地图样式时,通常需要提供相应的版权信息。例如,对于 Stamen Terrain 样式,可以通过 attr 参数添加版权信息,如下所示:

    # 使用 Stamen Terrain 样式创建地图
    m_stamen = folium.Map(
        location=[39.9, 116.4],
        zoom_start=10,
        tiles='Stamen Terrain',
        attr='&copy; <a href="http://stamen.com">Stamen Design</a>'
    )
    

    提供版权信息不仅符合使用条款,还可以帮助用户了解地图数据的来源。确保在使用自定义地图样式时,根据相应的地图服务提供者要求,正确添加版权信息。

    使用自定义地图服务

    Folium 也支持使用自定义地图服务。可以使用提供的 URL 模板来创建地图样式。在本例中,我们将使用高德地图的服务:

    import folium
    
    # 创建基础地图,不添加默认图层
    m = folium.Map(location=[39.9, 116.4], zoom_start=10, tiles=None)
    
    # 添加高德地图图层
    folium.TileLayer(
        tiles='http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
        attr='高德地图',
        subdomains=['1', '2', '3', '4']  # 子域名
    ).add_to(m)
    
  • tiles: 传入自定义的 URL 模板。
  • attr: 地图的版权信息,可以提供给用户。
  • 显示地图

    在 Jupyter Notebook 中,可以直接显示地图,或者将其保存为 HTML 文件:

    # 保存为 HTML 文件
    m_custom.save('custom_map.html')
    

    也可以将 Folium 地图直接转换为 HTML 字符串,而不保存到文件。可以使用 m._to_html() 方法来实现。

    交互控制

    用户可以控制 Folium 地图的交互行为,包括固定缩放比例、限制视野范围、禁止缩放和禁止移动。

    固定缩放比例

    在 Folium 中,你可以通过设置地图的最大和最小缩放级别来限制缩放比例。这样用户就无法放大或缩小超出指定的范围。

    import folium
    
    # 创建基础地图,设置最大和最小缩放级别
    m = folium.Map(location=[39.9, 116.4], zoom_start=10, max_zoom=10, min_zoom=8)
    
    # 保存地图
    m.save('fixed_zoom_map.html')
    

    固定视野范围

    虽然 Folium 不直接提供固定视野范围的功能,但可以通过设置地图的边界和视野中心来限制用户的视野范围。使用 fit_bounds 方法可以让地图自动调整到特定的边界。

    # 定义视野范围
    bounds = [[39.8, 116.3], [40.0, 116.5]]
    m.fit_bounds(bounds)
    
    # 保存地图
    m.save('fixed_bounds_map.html')
    

    禁止缩放

    如果希望完全禁止用户缩放地图,可以设置 scrollWheelZoom 参数为 False,并同时设置最大和最小缩放级别相同。

    m = folium.Map(location=[39.9, 116.4], zoom_start=10, max_zoom=10, min_zoom=10, control_scale=True)
    
    # 禁止滚轮缩放
    m.options['scrollWheelZoom'] = False
    
    # 保存地图
    m.save('no_zoom_map.html')
    

    禁止移动

    要禁止用户移动地图,可以使用 dragging 参数设置为 False。这将锁定地图的位置,用户无法通过拖动来改变视野。

    m = folium.Map(location=[39.9, 116.4], zoom_start=10, dragging=False)
    
    # 保存地图
    m.save('no_drag_map.html')
    

    添加几何图形和点击事件

    Folium 是一个强大的 Python 库,用于创建交互式地图。在这篇文章中,我们将学习如何在地图上添加点、线、面和圆,并为这些元素添加点击事件,以增强用户的互动体验。

    添加点(Marker)及点击事件

    点通常用于标识特定位置。可以使用 folium.Marker 添加标记,并为其添加点击事件。

    # 添加标记并添加点击事件
    marker = folium.Marker(
        location=[39.9, 116.4],
        popup='北京',
        icon=folium.Icon(color='blue')
    ).add_to(m)
    marker.add_child(folium.Popup('欢迎来到北京!', sticky=True))
    

    添加线(Polyline)及点击事件

    线用于连接多个点。使用 folium.PolyLine 创建线条,并为其添加点击事件。

    # 添加线并添加点击事件
    points = [[39.9, 116.4], [39.8, 116.5], [39.7, 116.4]]
    line = folium.PolyLine(locations=points, color='green', weight=5)
    line.add_to(m)
    line.add_child(folium.Popup('这是连接的线条!', sticky=True))
    

    添加面(Polygon)及点击事件

    面用于表示区域。可以使用 folium.Polygon 创建多边形,并为其添加点击事件。

    # 添加面并添加点击事件
    polygon_points = [[39.9, 116.4], [39.8, 116.5], [39.8, 116.3]]
    polygon = folium.Polygon(
        locations=polygon_points,
        color='red',
        fill=True,
        fill_color='orange',
        fill_opacity=0.5
    )
    polygon.add_to(m)
    polygon.add_child(folium.Popup('这是一个区域!', sticky=True))
    

    添加圆(Circle)及点击事件

    圆形用于表示特定区域,使用 folium.Circle 创建,并添加点击事件。

    # 添加圆并添加点击事件
    circle = folium.Circle(
        location=[39.9, 116.4],
        radius=1000,
        color='blue',
        fill=True,
        fill_color='blue',
        fill_opacity=0.2
    )
    circle.add_to(m)
    circle.add_child(folium.Popup('这是一个圆形区域!', sticky=True))
    

    图层加载

    Folium 基于 Leaflet,支持加载多种图层,例如瓦片地图、WMS 图层(Web Map Service)和 GeoJSON 数据。这使得用户可以更灵活地在地图上展示不同类型的信息。下面详细介绍如何添加这些图层。

    瓦片地图

    Folium 支持多种内置的瓦片地图样式,用户可以通过 tiles 参数选择不同的样式。例如,使用 CartoDB 提供的瓦片:

    import folium
    
    # 创建基础地图,使用 CartoDB 瓦片
    m = folium.Map(location=[39.9, 116.4], zoom_start=10, tiles='CartoDB positron')
    
    # 保存地图
    m.save('tile_map.html')
    

    WMS 图层

    WMS 图层允许用户加载地图服务器上的动态地图服务。通过 Folium,可以使用 WmsTileLayer 来添加 WMS 图层。

    # 添加 WMS 图层
    wms_url = 'https://ahocevar.com/geoserver/wms'
    wms_layer = folium.WmsTileLayer(
        wms_url,
        name='WMS Layer',
        layers='ne:ne',
        fmt='image/png',
        transparent=True
    ).add_to(m)
    
    # 添加图层控制器
    folium.LayerControl().add_to(m)
    
    # 保存地图
    m.save('wms_map.html')
    

    GeoJSON 数据

    可以通过 Folium 加载 GeoJSON 数据,并在地图上展示地理信息。使用 GeoJson 类来添加 GeoJSON 图层。

    import folium
    
    # 创建基础地图,设置最大和最小缩放级别
    m = folium.Map(location=[39.9, 116.4], zoom_start=10, max_zoom=20, min_zoom=1)
    
    # 示例 GeoJSON 数据,包含一个面(Polygon)
    geojson_data = {
        "type": "FeatureCollection",
        "features": [
            {
                "type": "Feature",
                "geometry": {
                    "type": "Polygon",
                    "coordinates": [
                        [
                            [116.3, 39.8],  # 左下角
                            [116.5, 39.8],  # 右下角
                            [116.5, 40.0],  # 右上角
                            [116.3, 40.0],  # 左上角
                            [116.3, 39.8]   # 回到左下角以闭合面
                        ]
                    ]
                },
                "properties": {"name": "自定义区域"}
            }
        ]
    }
    
    # 添加 GeoJSON 图层
    folium.GeoJson(geojson_data, name='GeoJSON Layer', style_function=lambda x: {
        'fillColor': 'blue', 
        'color': 'black', 
        'weight': 2, 
        'fillOpacity': 0.5
    }).add_to(m)
    
    # 添加图层控制器
    folium.LayerControl().add_to(m)
    
    # 保存地图
    m.save('geojson_map.html')
    

    图层控制

    在 Folium 中,图层控制器允许用户在地图上切换和管理不同的图层。这是增强地图交互性的一个重要功能,用户可以根据需要显示或隐藏不同的图层。

    添加图层

    首先,我们需要创建不同的图层,例如标记、线条和瓦片图层。以下是一个示例,展示如何创建多个图层并添加图层控制器。

    import folium
    
    # 创建基础地图
    m = folium.Map(location=[39.9, 116.4], zoom_start=10)
    
    # 添加标记
    marker = folium.Marker(location=[39.9, 116.4], popup='北京', name='标记层').add_to(m)
    
    # 添加线
    points = [[39.9, 116.4], [39.8, 116.5]]
    line = folium.PolyLine(locations=points, color='green', weight=5, name='线层').add_to(m)
    
    # 添加面
    polygon_points = [[39.9, 116.4], [39.8, 116.5], [39.8, 116.3]]
    polygon = folium.Polygon(locations=polygon_points, color='red', fill=True, fill_color='orange', fill_opacity=0.5, name='面层').add_to(m)
    
    # 添加瓦片图层,确保包含版权信息
    folium.TileLayer('Stamen Terrain', name='地形图', attr='&copy; <a href="http://stamen.com">Stamen Design</a>').add_to(m)
    folium.TileLayer('CartoDB positron', name='CartoDB 亮色图', attr='&copy; <a href="http://cartodb.com/attributions">CartoDB</a>').add_to(m)
    
    # 添加图层控制器
    folium.LayerControl().add_to(m)
    
    # 保存地图
    m.save('layer_control_map.html')
    
  • 添加图层:使用不同的图层类型(如 MarkerPolylinePolygonTileLayer)创建地图元素。
  • 图层控制器:通过调用 folium.LayerControl() 来创建图层控制器。它会自动识别添加到地图上的图层,并生成相应的切换按钮。
  • 定制图层控制器

    在创建 LayerControl 时,可以使用以下参数来定制其行为:

  • position:设置控制器的位置(如 ‘topright’, ‘bottomleft’ 等)。
  • collapsed:设置是否默认收起控制器(True 或 False)。
  • 示例代码:

    # 添加图层控制器,设置位置和是否收起
    folium.LayerControl(position='topright', collapsed=False).add_to(m)
    

    作者:T0uken

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【Python】Folium:调用Leaflet交互地图

    发表回复