StarFire_xm
  • 文章
  • 粉丝
  • 评论

h3热力图

2025-11-19 14:17:550 次浏览0 次评论技能类型: h3热力图

https://observablehq.com/d/31ab0068a4664578 是一个 Observable Notebook 的案例(类似于echarts的一个案例库),展示了如何使用 Mapbox 和 H3(Hexagonal Hierarchical Geospatial Indexing System)来创建热力图。

其中:Mapbox 的 API Token 是 Mapbox 平台的授权凭证,好像不是免费的要付费



生成热力图结合h3使用的代码案例(h3库本质只是把h3索引模式转成GeoJSON数据而已):

import mapboxgl from 'mapbox-gl';
import { h3SetToFeatureCollection } from 'h3-js';

mapboxgl.accessToken = 'your-mapbox-access-token';  // 替换为你的 Mapbox Token

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v11',
  center: [116.397389, 39.908860],
  zoom: 10
});

// 生成 H3 索引
const h3Indexes = ['81003fffffffffff', '81007fffffffffff'];  // 示例 H3 索引
const geojsonData = h3SetToFeatureCollection(h3Indexes, h3Index => ({
  value: Math.random() * 10  // 随机权重
}));

// 加载 GeoJSON 数据
map.on('load', () => {
  map.addSource('heatmapSource', {
    type: 'geojson',
    data: geojsonData
  });

  map.addLayer({
    id: 'heatmapLayer',
    type: 'heatmap',
    source: 'heatmapSource',
    paint: {
      'heatmap-weight': ['get', 'value'],
      'heatmap-color': [
        'interpolate',
        ['linear'],
        ['heatmap-density'],
        0, 'rgba(0,0,255,0)',
        0.2, 'royalblue',
        0.4, 'cyan',
        0.6, 'lime',
        0.8, 'yellow',
        1, 'red'
      ],
      'heatmap-radius': ['interpolate', ['linear'], ['zoom'], 0, 10, 9, 50],
      'heatmap-opacity': 0.8
    }
  });
  
  // 添加城市名称标注图层
  map.addLayer({
    id: 'cityLabels',
    type: 'symbol',
    source: 'heatmapSource',
    layout: {
      'text-field': ['get', 'cityName'],  // 从 GeoJSON 的 properties 中获取城市名称
      'text-size': 12,
      'text-anchor': 'top'
    },
    paint: {
      'text-color': '#000000'
    }
  });
});


前端用到的三方库有:

   npm install mapbox-gl h3-js


  Mapbox GL JS:

     .用于地图渲染和交互

     .提供热力图、点图、矢量图层等功能

     .需要通过 Mapbox API Token 进行授权


  H3:

   .用于地理数据的六边形网格化处理

   .提供高效的地理数据索引和聚合功能

   .在热力图中,H3 索引可以用于生成六边形区域


  核心使用组合:生成 H3 索引 → 转换为 GeoJSON → 使用 Mapbox 渲染热力图


服务端数据:

    方式1:存储H3索引(以h3索引的方式生成热力图案例-其本质h3只是用来生成GeoJSON 数据而已)

[
  {
    "h3Index": "81003fffffffffff",//必要固定字段
    "value": 10,  // 热力图权重 必要固定字段
    "cityName": "Beijing"  // 自定义字段 城市名称
    "category": "A",  // 自定义的字段  这里分类信息(可选)
  },
  {
    "h3Index": "81007fffffffffff",
    "value": 5,
    "cityName": "Beijing"  // 自定义字段 城市名称
    "category": "B"
  }
]



前端转换示例代码:
import { h3SetToFeatureCollection } from 'h3-js';

// 示例服务端返回的 H3 索引数据
const h3Data = [
  { h3Index: "81003fffffffffff", value: 10, cityName: "Beijing" },
  { h3Index: "81007fffffffffff", value: 5, cityName: "Shanghai" }
];

// 转换为 GeoJSON
const geojsonData = h3SetToFeatureCollection(
  h3Data.map(item => item.h3Index),  // 提取 H3 索引
  h3Index => ({
    value: h3Data.find(item => item.h3Index === h3Index).value,  // 映射权重
    cityName: h3Data.find(item => item.h3Index === h3Index).cityName  // 保留城市属性
  })
);

console.log(geojsonData);

转换后结构应该是:
geojsonData={
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "value": 10,  // 热力图权重
        "cityName": "Beijing"  // 城市名称
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [116.397389, 39.908860],
            [116.400000, 39.909000],
            [116.395000, 39.907000],
            [116.397389, 39.908860]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "value": 5,
        "cityName": "Beijing"  // 城市名称
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [116.400000, 39.909000],
            [116.403000, 39.910000],
            [116.398000, 39.908000],
            [116.400000, 39.909000]
          ]
        ]
      }
    }
  ]
}

    

    方式2:存储GeoJSON数据

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "value": 10,  // 热力图权重
        "cityName": "Beijing"  // 自定义字段 城市名称
        "category": "A",  //  自定义字段 分类信息(可选)
      },
      "geometry": {
        "type": "Point",  // 或 "Polygon"
        "coordinates": [116.397389, 39.908860]  // 经纬度坐标
      }
    },
    {
      "type": "Feature",
      "properties": {
        "value": 5,
        "cityName": "Beijing"  // 自定义字段 城市名称
        "category": "B"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [116.400000, 39.909000]
      }
    }
  ]
}



服务器存储哪种类型指标参考:
     .数据量

           如果数据量大,建议存储 H3 索引,前端或中间层动态转换为 GeoJSON

           如果数据量小,可以直接存储 GeoJSON

     .动态分辨率

           如果需要根据地图缩放级别动态调整分辨率,存储 H3 索引更合适

           如果分辨率固定,存储 GeoJSON 更简单

      .前端复杂度

           储 H3 索引需要前端或中间层处理

           存储 GeoJSON 前端可以直接使用


      结论推荐:

           大规模地理数据:存储 H3 索引,前端使用 H3 库动态转换为 GeoJSON

          小规模地理数据:直接存储 GeoJSON,前端直接加载渲染

    发表

    还没有评论哦,来抢个沙发吧!