Atlaslog
Atlaslog / Examples / Cesium / Heatmap Points
Cesium · Runnable Example

Heatmap Points

Runnable Cesium example: Heatmap Points. Open the live demo, read the complete source, and copy the file into your project. No build step or API key.

Open standalone → Chinese notes All Cesium examples
/demos/cesium-heatmap-points.htmlLIVE
single HTML file · CDN dependencies onlyinterface may contain Chinese labels

Source

demos/cesium-heatmap-points.html
<!--
  示例:用图标叠加做出热力效果
  要点:canvas 生成径向渐变贴图,按到簇中心的距离算出权重,权重映射到颜色与尺寸
  依赖:CesiumJS 1.121 · jsDelivr CDN,渐变贴图由 canvas 实时生成
-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="robots" content="noindex,follow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>热力图点</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/cesium@1.121.0/Build/Cesium/Widgets/widgets.css">
<style>
  html,body{height:100%;margin:0}
  body{background:#0e1116;color:#e6e8ec;overflow:hidden;
       font:13px/1.6 -apple-system,"Segoe UI","PingFang SC",sans-serif}
  #c{height:100%}
  .hud{position:absolute;left:12px;top:12px;z-index:5;background:rgba(23,28,35,.9);
       border:1px solid #2a313b;border-radius:6px;padding:9px 12px;font-size:12px;
       color:#a2a9b6;max-width:250px}
  .hud b{color:#e6e8ec;font-weight:600}
  .hud .row{margin-top:6px}
  .legend{height:8px;border-radius:4px;margin-top:6px;
       background:linear-gradient(90deg,#4d9bff,#3fe0b0,#ffd666,#ff5c5c)}
  .scale{display:flex;justify-content:space-between;font-size:11px;color:#7f8899}
  input[type=range]{width:100%;margin-top:6px}
  .cesium-viewer-bottom .cesium-widget-credits,.cesium-viewer-animationContainer,
  .cesium-viewer-timelineContainer{display:none!important}
</style>
</head>
<body>
<div id="c"></div>
<div class="hud">
  <div><b>热度分布</b></div>
  <div>亮度按簇中心距离递减</div>
  <div class="legend"></div>
  <div class="scale"><span>低</span><span>高</span></div>
  <div class="row"><input id="radius" type="range" min="0.3" max="2" step="0.1" value="1"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/cesium@1.121.0/Build/Cesium/Cesium.js"></script>
<script>
(function () {
  'use strict';

  var viewer = new Cesium.Viewer('c', {
    baseLayer: false,
    baseLayerPicker: false, geocoder: false, homeButton: false,
    sceneModePicker: false, navigationHelpButton: false,
    animation: false, timeline: false, fullscreenButton: false,
    infoBox: false, selectionIndicator: false
  });

  var scene = viewer.scene;
  scene.globe.baseColor = Cesium.Color.fromCssColorString('#1c2733');
  scene.backgroundColor = Cesium.Color.fromCssColorString('#0e1116');
  scene.skyBox.show = false;
  scene.sun.show = false;
  scene.moon.show = false;
  if (scene.skyAtmosphere) scene.skyAtmosphere.show = false;

  /* 径向渐变贴图:中心白、边缘全透明,叠起来就是热力光斑 */
  function glowTexture() {
    var size = 64;
    var canvas = document.createElement('canvas');
    canvas.width = canvas.height = size;
    var ctx = canvas.getContext('2d');
    var g = ctx.createRadialGradient(size / 2, size / 2, 1, size / 2, size / 2, size / 2);
    g.addColorStop(0, 'rgba(255,255,255,0.95)');
    g.addColorStop(0.45, 'rgba(255,255,255,0.35)');
    g.addColorStop(1, 'rgba(255,255,255,0)');
    ctx.fillStyle = g;
    ctx.fillRect(0, 0, size, size);
    return canvas;
  }

  var TEXTURE = glowTexture();

  /* 三个簇:长三角一带,半径单位为度 */
  var CLUSTERS = [
    { lng: 121.4737, lat: 31.2304, r: 0.30, weight: 0.55 },
    { lng: 120.5853, lat: 31.2989, r: 0.20, weight: 0.28 },
    { lng: 120.1551, lat: 30.2741, r: 0.18, weight: 0.17 }
  ];

  var seed = 20261027;
  function rand() {
    seed = (seed * 1103515245 + 12345) & 0x7fffffff;
    return seed / 0x7fffffff;
  }
  function gauss() {
    var u = Math.max(rand(), 1e-6);
    var v = rand();
    return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
  }

  var STOPS = [
    [0.00, [77, 155, 255]],
    [0.40, [63, 224, 176]],
    [0.70, [255, 214, 102]],
    [1.00, [255, 92, 92]]
  ];

  function heatColor(w) {
    for (var i = 1; i < STOPS.length; i++) {
      if (w <= STOPS[i][0] || i === STOPS.length - 1) {
        var a = STOPS[i - 1], b = STOPS[i];
        var k = (w - a[0]) / (b[0] - a[0]);
        var r = Math.round(a[1][0] + (b[1][0] - a[1][0]) * k);
        var g = Math.round(a[1][1] + (b[1][1] - a[1][1]) * k);
        var bl = Math.round(a[1][2] + (b[1][2] - a[1][2]) * k);
        return Cesium.Color.fromBytes(r, g, bl, 255).withAlpha(0.55 + w * 0.35);
      }
    }
    return Cesium.Color.WHITE;
  }

  var spots = [];
  for (var n = 0; n < 260; n++) {
    var pick = rand();
    var acc = 0, cluster = CLUSTERS[0];
    for (var c = 0; c < CLUSTERS.length; c++) {
      acc += CLUSTERS[c].weight;
      if (pick <= acc) { cluster = CLUSTERS[c]; break; }
    }
    var dist = Math.abs(gauss()) * cluster.r;
    var angle = rand() * Math.PI * 2;
    var lng = cluster.lng + Math.cos(angle) * dist;
    var lat = cluster.lat + Math.sin(angle) * dist * 0.75;
    var weight = Math.max(0, 1 - dist / (cluster.r * 1.9));
    spots.push({ lng: lng, lat: lat, w: weight });
  }

  var baseScale = [];
  spots.forEach(function (s) {
    var scale = 0.35 + s.w * 1.15;
    baseScale.push(scale);
    viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(s.lng, s.lat, 0),
      billboard: {
        image: TEXTURE,
        color: heatColor(s.w),
        scale: scale,
        disableDepthTestDistance: Number.POSITIVE_INFINITY
      }
    });
  });

  var entities = viewer.entities.values;

  document.getElementById('radius').addEventListener('input', function () {
    var k = parseFloat(this.value);
    for (var i = 0; i < entities.length; i++) {
      if (entities[i].billboard) entities[i].billboard.scale = baseScale[i] * k;
    }
  });

  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(120.98, 30.98, 210000),
    orientation: { heading: 0, pitch: Cesium.Math.toRadians(-82), roll: 0 },
    duration: 0
  });
})();
</script>
</body>
</html>
Language: the code and this page are in English; the full tutorial and API notes for this example are in Chinese. The demo itself is the authoritative version — it runs exactly as shown.

More Cesium examples

Cesium · EXAMPLEHigh Dynamic Range Cesium · EXAMPLEHtml Overlays Cesium · EXAMPLEI3s 3D Object Layer