7
0

heatmap-db.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // 热力图变量
  2. let heatmapLayer;
  3. let heatmapData = [];
  4. let isHeatmapVisible = true;
  5. let pointCount = 1000;
  6. let maxIntensity = 10;
  7. // 根据相机高度计算合适的热力图参数
  8. function getHeatmapParameters(cameraHeight) {
  9. // 高度越高,需要更大的覆盖范围和更大的点半径
  10. let radius;
  11. let pointRange;
  12. if (cameraHeight < 10000) { // 近距离
  13. radius = 0.005; // 约500米
  14. pointRange = 0.1; // 约10公里范围
  15. } else if (cameraHeight < 100000) { // 中距离
  16. radius = 0.02; // 约2公里
  17. pointRange = 0.5; // 约50公里范围
  18. } else { // 远距离
  19. radius = 0.1; // 约10公里
  20. pointRange = 2; // 约200公里范围
  21. }
  22. return { radius, pointRange };
  23. }
  24. // 创建或更新热力图
  25. function updateHeatmap() {
  26. // 获取当前相机位置
  27. const cameraPosition = viewer.camera.positionCartographic;
  28. const cameraHeight = Math.round(Cesium.Cartographic.fromCartesian(viewer.camera.position).height);
  29. // 获取适合当前高度的参数
  30. const { radius, pointRange } = getHeatmapParameters(cameraHeight);
  31. // 确定当前视图中心和范围
  32. const center = {
  33. lng: Cesium.Math.toDegrees(cameraPosition.longitude),
  34. lat: Cesium.Math.toDegrees(cameraPosition.latitude),
  35. radius: pointRange
  36. };
  37. // // 如果没有数据或数据点不足,生成新数据
  38. // if (heatmapData.length < pointCount * 0.7) {
  39. // heatmapData = generateHeatmapData(pointCount, center);
  40. // }
  41. // 清除旧的热力图图层
  42. if (heatmapLayer) {
  43. viewer.imageryLayers.remove(heatmapLayer);
  44. }
  45. if (!isHeatmapVisible) return;
  46. // 创建热力图canvas
  47. const canvas = document.createElement('canvas');
  48. const size = 1024; // 热力图大小
  49. canvas.width = size;
  50. canvas.height = size;
  51. // 配置heatmap.js
  52. const heatmapInstance = h337.create({
  53. container: canvas,
  54. radius: radius * size / (pointRange * 2), // 根据画布大小调整半径
  55. maxOpacity: 0.6,
  56. minOpacity: 0,
  57. blur: 0.85,
  58. gradient: {
  59. 0.4: 'blue',
  60. 0.5: 'cyan',
  61. 0.6: 'green',
  62. 0.7: 'yellow',
  63. 0.8: 'orange',
  64. 0.9: 'red'
  65. }
  66. });
  67. // 转换数据坐标到画布坐标
  68. const points = heatmapData.map(point => {
  69. return {
  70. x: ((point.x - (center.lng - pointRange)) / (pointRange * 2)) * size,
  71. y: ((point.y - (center.lat - pointRange)) / (pointRange * 2)) * size,
  72. value: point.value
  73. };
  74. }).filter(point => {
  75. // 过滤掉画布外的点
  76. return point.x >= 0 && point.x <= size && point.y >= 0 && point.y <= size;
  77. });
  78. // 设置热力图数据
  79. heatmapInstance.setData({
  80. max: maxIntensity,
  81. min: 1,
  82. data: points
  83. });
  84. // 创建Cesium图像图层
  85. const extent = new Cesium.Rectangle(
  86. Cesium.Math.toRadians(center.lng - pointRange),
  87. Cesium.Math.toRadians(center.lat - pointRange),
  88. Cesium.Math.toRadians(center.lng + pointRange),
  89. Cesium.Math.toRadians(center.lat + pointRange)
  90. );
  91. heatmapLayer = viewer.imageryLayers.addImageryProvider(
  92. new Cesium.SingleTileImageryProvider({
  93. url: canvas.toDataURL(),
  94. rectangle: extent
  95. })
  96. );
  97. // 设置图层透明度
  98. heatmapLayer.alpha = 0.7;
  99. }
  100. // 初始化热力图
  101. updateHeatmap();
  102. // 监听相机移动事件,当相机停止移动后更新热力图
  103. let cameraMoveTimeout;
  104. viewer.camera.moveEnd.addEventListener(() => {
  105. clearTimeout(cameraMoveTimeout);
  106. // 延迟更新,避免频繁刷新
  107. cameraMoveTimeout = setTimeout(updateHeatmap, 300);
  108. });