You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于经纬度极值在地图绘制矩形边界框及添加Tooltip的实现咨询

如何用边界框和工具提示可视化分组地图数据

嘿,这事儿其实不难!你已经握有核心的分组坐标和实体数据,接下来咱们用两种简单易用的工具就能搞定需求——一个是适合前端网页的Leaflet库,另一个是适配Python数据处理的Plotly。我给你拆成步骤讲:

第一步:先整理你的数据

首先得把你给出的原始数据转成结构化格式,因为原始的“33.29 (122.45)”这种格式需要拆分出纬度和经度。比如整理成下面这种结构(以你的示例为例):

结构化数据示例

// JS版本
const groups = [
  { group: 'a', entities: 44, minlat: 33.29, minlong: -122.45, maxlat: 41.32, maxlong: -111.75 },
  { group: 'b', entities: 39, minlat: 42.53, minlong: -110.97, maxlat: 48.51, maxlong: -94.90 },
  { group: 'c', entities: 37, minlat: 42.46, minlong: -100.34, maxlat: 45.79, maxlong: -94.83 },
  { group: 'd', entities: 31, minlat: 32.78, minlong: -83.97, maxlat: 35.73, maxlong: -77.86 },
  { group: 'e', entities: 30, minlat: 40.41, minlong: -96.41, maxlat: 43.07, maxlong: -89.40 },
  { group: 'f', entities: 28, minlat: 39.81, minlong: -80.47, maxlat: 42.13, maxlong: -76.78 }
];
# Python版本
groups = [
    {"group": "a", "entities": 44, "minlat": 33.29, "minlong": -122.45, "maxlat": 41.32, "maxlong": -111.75},
    {"group": "b", "entities": 39, "minlat": 42.53, "minlong": -110.97, "maxlat": 48.51, "maxlong": -94.90},
    {"group": "c", "entities": 37, "minlat": 42.46, "minlong": -100.34, "maxlat": 45.79, "maxlong": -94.83},
    {"group": "d", "entities": 31, "minlat": 32.78, "minlong": -83.97, "maxlat": 35.73, "maxlong": -77.86},
    {"group": "e", "entities": 30, "minlat": 40.41, "minlong": -96.41, "maxlat": 43.07, "maxlong": -89.40},
    {"group": "f", "entities": 28, "minlat": 39.81, "minlong": -80.47, "maxlat": 42.13, "maxlong": -76.78}
]

注意:我假设你的经度是西经,所以加了负号,如果是东经就去掉哦!


方法一:用Leaflet(前端网页实现)

Leaflet是轻量且灵活的开源地图库,直接在浏览器里就能跑,步骤如下:

  1. 引入Leaflet的资源:在HTML里加CSS和JS链接
  2. 创建地图容器:一个带ID的div
  3. 初始化地图:设置中心坐标和缩放级别
  4. 循环绘制边界框并绑定工具提示

完整代码示例

<!DOCTYPE html>
<html>
<head>
    <title>Group Bounding Boxes</title>
    <!-- 引入Leaflet CSS -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
    <!-- 引入Leaflet JS -->
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
    <style>
        #map { height: 600px; width: 100%; }
    </style>
</head>
<body>
    <div id="map"></div>

    <script>
        // 结构化数据
        const groups = [
            { group: 'a', entities: 44, minlat: 33.29, minlong: -122.45, maxlat: 41.32, maxlong: -111.75 },
            { group: 'b', entities: 39, minlat: 42.53, minlong: -110.97, maxlat: 48.51, maxlong: -94.90 },
            { group: 'c', entities: 37, minlat: 42.46, minlong: -100.34, maxlat: 45.79, maxlong: -94.83 },
            { group: 'd', entities: 31, minlat: 32.78, minlong: -83.97, maxlat: 35.73, maxlong: -77.86 },
            { group: 'e', entities: 30, minlat: 40.41, minlong: -96.41, maxlat: 43.07, maxlong: -89.40 },
            { group: 'f', entities: 28, minlat: 39.81, minlong: -80.47, maxlat: 42.13, maxlong: -76.78 }
        ];

        // 初始化地图,设置中心为美国中部,缩放级别4
        const map = L.map('map').setView([39.8283, -98.5795], 4);

        // 添加地图底图(OpenStreetMap)
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(map);

        // 循环遍历每个分组,绘制边界框
        groups.forEach(group => {
            // 定义边界框的四个角坐标:[西南, 东北]
            const bounds = [
                [group.minlat, group.minlong],
                [group.maxlat, group.maxlong]
            ];

            // 创建矩形图层,设置样式
            const rect = L.rectangle(bounds, {
                color: '#ff7800',
                weight: 2,
                fillColor: '#ff7800',
                fillOpacity: 0.1
            }).addTo(map);

            // 绑定工具提示,自定义显示内容
            rect.bindTooltip(`
                <strong>分组:${group.group}</strong><br>
                实体数量:${group.entities}<br>
                边界范围:<br>
                最小纬度: ${group.minlat}, 最小经度: ${group.minlong}<br>
                最大纬度: ${group.maxlat}, 最大经度: ${group.maxlong}
            `, { permanent: false, sticky: true });
        });
    </script>
</body>
</html>

把这段代码保存成HTML文件,直接打开就能看到效果!


方法二:用Plotly(Python实现)

如果你习惯用Python处理数据,Plotly的scattermapbox可以轻松实现这个需求,还能导出交互式HTML或者图片。

完整代码示例

import plotly.graph_objects as go

# 结构化数据
groups = [
    {"group": "a", "entities": 44, "minlat": 33.29, "minlong": -122.45, "maxlat": 41.32, "maxlong": -111.75},
    {"group": "b", "entities": 39, "minlat": 42.53, "minlong": -110.97, "maxlat": 48.51, "maxlong": -94.90},
    {"group": "c", "entities": 37, "minlat": 42.46, "minlong": -100.34, "maxlat": 45.79, "maxlong": -94.83},
    {"group": "d", "entities": 31, "minlat": 32.78, "minlong": -83.97, "maxlat": 35.73, "maxlong": -77.86},
    {"group": "e", "entities": 30, "minlat": 40.41, "minlong": -96.41, "maxlat": 43.07, "maxlong": -89.40},
    {"group": "f", "entities": 28, "minlat": 39.81, "minlong": -80.47, "maxlat": 42.13, "maxlong": -76.78}
]

fig = go.Figure()

# 遍历每个分组,绘制矩形边界框
for group in groups:
    # 矩形的四个点坐标(Plotly是[lon, lat]顺序)
    lons = [group.minlong, group.maxlong, group.maxlong, group.minlong, group.minlong]
    lats = [group.minlat, group.minlat, group.maxlat, group.maxlat, group.minlat]
    
    # 添加矩形轨迹
    fig.add_trace(go.Scattermapbox(
        lon=lons,
        lat=lats,
        mode='lines',
        name=group['group'],
        line=dict(width=2, color='#ff7800'),
        fill='toself',
        fillcolor='rgba(255, 120, 0, 0.1)',
        # 工具提示内容
        hovertemplate=f'''
            <b>分组:{group['group']}</b><br>
            实体数量:{group['entities']}<br>
            最小纬度: {group['minlat']}<br>
            最小经度: {group['minlong']}<br>
            最大纬度: {group['maxlat']}<br>
            最大经度: {group['maxlong']}<br>
            <extra></extra>
        '''
    ))

# 设置地图布局
fig.update_layout(
    mapbox_style='open-street-map',
    mapbox_center={"lat": 39.8283, "lon": -98.5795},
    mapbox_zoom=4,
    height=600,
    margin={"r":0,"t":0,"l":0,"b":0}
)

# 显示图表
fig.show()

# 导出为HTML文件(可选)
# fig.write_html('group_bounding_boxes.html')

运行这段代码会弹出一个交互式窗口,鼠标 hover 在矩形上就能看到工具提示!


几个小提示

  • 经纬度顺序:不同库的坐标顺序可能不一样,Leaflet是[lat, lon],Plotly是[lon, lat],别搞混了!
  • 样式自定义:你可以修改颜色、透明度、线宽这些参数,让地图更符合你的需求。
  • 数据解析:如果你的原始数据是CSV或者其他格式,可以用Python的pandas或者JS的d3.csv来批量解析,不用手动整理。

内容的提问来源于stack exchange,提问作者Chris Decker

火山引擎 最新活动