123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- // 热力图变量
- let heatmapLayer;
- let heatmapData = [];
- let isHeatmapVisible = true;
- let pointCount = 1000;
- let maxIntensity = 10;
- // 根据相机高度计算合适的热力图参数
- function getHeatmapParameters(cameraHeight) {
- // 高度越高,需要更大的覆盖范围和更大的点半径
- let radius;
- let pointRange;
- if (cameraHeight < 10000) { // 近距离
- radius = 0.005; // 约500米
- pointRange = 0.1; // 约10公里范围
- } else if (cameraHeight < 100000) { // 中距离
- radius = 0.02; // 约2公里
- pointRange = 0.5; // 约50公里范围
- } else { // 远距离
- radius = 0.1; // 约10公里
- pointRange = 2; // 约200公里范围
- }
- return { radius, pointRange };
- }
- // 创建或更新热力图
- function updateHeatmap() {
- // 获取当前相机位置
- const cameraPosition = viewer.camera.positionCartographic;
- const cameraHeight = Math.round(Cesium.Cartographic.fromCartesian(viewer.camera.position).height);
- // 获取适合当前高度的参数
- const { radius, pointRange } = getHeatmapParameters(cameraHeight);
- // 确定当前视图中心和范围
- const center = {
- lng: Cesium.Math.toDegrees(cameraPosition.longitude),
- lat: Cesium.Math.toDegrees(cameraPosition.latitude),
- radius: pointRange
- };
- // // 如果没有数据或数据点不足,生成新数据
- // if (heatmapData.length < pointCount * 0.7) {
- // heatmapData = generateHeatmapData(pointCount, center);
- // }
- // 清除旧的热力图图层
- if (heatmapLayer) {
- viewer.imageryLayers.remove(heatmapLayer);
- }
- if (!isHeatmapVisible) return;
- // 创建热力图canvas
- const canvas = document.createElement('canvas');
- const size = 1024; // 热力图大小
- canvas.width = size;
- canvas.height = size;
- // 配置heatmap.js
- const heatmapInstance = h337.create({
- container: canvas,
- radius: radius * size / (pointRange * 2), // 根据画布大小调整半径
- maxOpacity: 0.6,
- minOpacity: 0,
- blur: 0.85,
- gradient: {
- 0.4: 'blue',
- 0.5: 'cyan',
- 0.6: 'green',
- 0.7: 'yellow',
- 0.8: 'orange',
- 0.9: 'red'
- }
- });
- // 转换数据坐标到画布坐标
- const points = heatmapData.map(point => {
- return {
- x: ((point.x - (center.lng - pointRange)) / (pointRange * 2)) * size,
- y: ((point.y - (center.lat - pointRange)) / (pointRange * 2)) * size,
- value: point.value
- };
- }).filter(point => {
- // 过滤掉画布外的点
- return point.x >= 0 && point.x <= size && point.y >= 0 && point.y <= size;
- });
- // 设置热力图数据
- heatmapInstance.setData({
- max: maxIntensity,
- min: 1,
- data: points
- });
- // 创建Cesium图像图层
- const extent = new Cesium.Rectangle(
- Cesium.Math.toRadians(center.lng - pointRange),
- Cesium.Math.toRadians(center.lat - pointRange),
- Cesium.Math.toRadians(center.lng + pointRange),
- Cesium.Math.toRadians(center.lat + pointRange)
- );
- heatmapLayer = viewer.imageryLayers.addImageryProvider(
- new Cesium.SingleTileImageryProvider({
- url: canvas.toDataURL(),
- rectangle: extent
- })
- );
- // 设置图层透明度
- heatmapLayer.alpha = 0.7;
- }
- // 初始化热力图
- updateHeatmap();
- // 监听相机移动事件,当相机停止移动后更新热力图
- let cameraMoveTimeout;
- viewer.camera.moveEnd.addEventListener(() => {
- clearTimeout(cameraMoveTimeout);
- // 延迟更新,避免频繁刷新
- cameraMoveTimeout = setTimeout(updateHeatmap, 300);
- });
|