1、引入插件
CesiumHeatmap-master.js
2、封装js
大概的实现步骤:
1)选择中心点:以某个指定点作为热力图的中心。
2)确定半径:定义一个半径来确定热力图的影响范围。
3)计算边界:基于半径计算出该范围的边界区域。
4)生成随机点:在边界区域内生成随机点来表示热力图中的数据分布。
5)绘制热力图:使用这些点的分布情况来以此形成热力图。
//-----------------加载热力图start------------------//
//图片
var image = new Image();
//最小值
let valueMin = 0;
//最大值
let valueMax = 200;
var randomRect = []; //存储随机生成的热力图,矩形,延迟方法
var randomid = 0; //id
//点,随机数,生成热力图
function PointRandomHeatMap() {
// viewer.clock.shouldAnimate = true;
var point = {
longitude: 108.45,
latitude: 33.9,
height: 11.409122369106317
}
var primitiveid = "test";
var radius = 200; //半径
var randiusPoint = 200; //点周围范围半径内
var rvalue = 150; //范围半径
// 计算边界
var west = point.longitude - Cesium.Math.toDegrees(rvalue / Cesium.Ellipsoid.WGS84.maximumRadius);
var south = point.latitude - Cesium.Math.toDegrees(rvalue / Cesium.Ellipsoid.WGS84.maximumRadius);
var east = point.longitude + Cesium.Math.toDegrees(rvalue / Cesium.Ellipsoid.WGS84.maximumRadius);
var north = point.latitude + Cesium.Math.toDegrees(rvalue / Cesium.Ellipsoid.WGS84.maximumRadius);
var bounds = new Cesium.Rectangle(west, south, east, north);
// 输出计算得到的边界
viewer.camera.setView({
destination: Cesium.Rectangle.fromDegrees(bounds.west, bounds.south, bounds.east, bounds.north)
});
// var data = getDatapoint(point, bounds, randiusPoint, 100); //数据
// 定义热力图的角度范围
var northeastDirectionRange = {
min: Math.PI / 6, // 45度,指向东北方向开始
max: 3 * Math.PI / 6 // 135度,指向东北方向结束
};
var data = getDatapoint(point, bounds, randiusPoint, 100,northeastDirectionRange);//数据
var heatMap;
var heatPrimitive = viewer.scene.primitives.add(
new Cesium.GroundPrimitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(bounds.west, bounds.south, bounds.east, bounds.north),
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
}),
}),
appearance: new Cesium.EllipsoidSurfaceAppearance({
aboveGround: true,
material: new Cesium.Material({
fabric: {
type: "Image",
uniforms: {
image: image.src,
},
},
}),
}),
})
);
heatPrimitive.id = primitiveid;
heatPrimitive.show = false;
SyncCreate(valueMin, valueMax, radius, data, heatPrimitive);
// viewer.clock.onTick.addEventListener(syncRadius);
//动态加载渲染
var synctimer1 = setInterval(function () {
console.log('4444444动态加载渲染',)
syncRadius();
}, 100);
randomRect.push({
id: heatPrimitive.id,
obj: {
heatmap: heatMap,
primitive: heatPrimitive,
synctimer: synctimer1
}
});
function syncRadius(params) {
//clearInterval(synctimer1);
radius++;
if (radius >= 100) {
radius = 0;
}
SyncCreate(valueMin, valueMax, radius, data, heatPrimitive);
//到达点后清除掉
if (radius == 80) {
ClearHeatMapSync('test')
clearInterval(synctimer1);
radius = 100.0;
heatMap.clearLayer();
viewer.scene.primitives.remove(heatPrimitive);
viewer.scene.requestRender(); // 请求一个新的渲染帧
viewer.entities.removeAll()
CameraFlyTo1(115.628414, 29.668894, 5000000); //改变默认初始地图高度
}
}
//生成
function SyncCreate(valueMin, valueMax, radius, data, heatPrimitive) {
viewer.scene.requestRender(); // 请求一个新的渲染帧
heatMap = CesiumHeatmap.create(
viewer, // 视图层
bounds, // 矩形坐标
{ // heatmap相应参数
backgroundColor: "rgba(0,0,0,0)",
radius: radius,
maxOpacity: .5,
minOpacity: 0,
blur: .75
}
);
heatMap.setWGS84Data(valueMin, valueMax, data);
heatMap.show(false);
CreateImageCanvasSync(heatMap, heatPrimitive);
}
}
// 计算范围内的随机点,限制在特定方向范围内生成
function getDatapoint(point, bounds, rp, length, directionRange) {
var data = [];
data.push({ x: point.longitude, y: point.latitude, value: valueMax });
for (var i = 0; i < length; i++) {
// 生成随机方位角,限制在给定的方向范围内
var bearing = Cesium.Math.randomBetween(directionRange.min, directionRange.max);
// 生成随机距离(在半径范围内)
var distance = Cesium.Math.randomBetween(0, rp);
// 根据中心点、方位角和距离计算生成点的经纬度坐标
var randompoint = calculatingTargetPoints(point, bearing, distance);
var x = randompoint.longitude;
var y = randompoint.latitude;
var value = Math.random() * 100;
data.push({ x: x, y: y, value: value });
}
return data;
}
//热力图数据渲染成图片,贴在地图上
function CreateImageCanvasSync(heatMap, heatPrimitive) {
//指定格式PNG,更新材质
image.src = heatMap._heatmap._renderer.canvas.toDataURL("image/jpg");
heatPrimitive.appearance.material.uniforms.image = image.src;
heatPrimitive.show = true;
if (heatMap.getLayer()) {
heatMap.clearLayer();
}
}
//清除结果
function ClearHeatMapSync(id) {
var ob = GetObj(id);
clearInterval(ob.b.obj.synctimer);
ob.b.obj.heatmap.clearLayer();
viewer.scene.primitives.remove(ob.b.obj.primitive);
randomRect.splice(ob.a, 1);
}
//根据id查找
function GetObj(id) {
for (var i = 0; i < randomRect.length; i++) {
if (randomRect[i].id == id) {
return {
a: i,
b: randomRect[i]
};
}
}
}
//----------------------------end热力图end----------------------//
3、调用
在页面引入封装的js,调用下方函数就可以
PointRandomHeatMap()
4、效果
1)、 热力图设置角度范围
var DirectionRange = {
min: Math.PI / 4, // 45度,指向东北方向开始
max: 3 * Math.PI / 4 // 135度,指向东北方向结束
};
利用数学中的计算方式,算出它的一个弧度
2)热力图圆圈显示
去掉DirectionRange 这个传参;
计算函数里面,代码改成
//计算范围内的随机点
function getDatapoint(point, bounds, rp, length) {
data = [];
data.push({
x: point.longitude,
y: point.latitude,
value: valueMax
});
for (var i = 0; i < length; i++) {
// 生成随机方位角(bearing)
var bearing = Cesium.Math.randomBetween(0, 2 * Math.PI);
// 生成随机距离(在半径范围内)
var distance = Cesium.Math.randomBetween(0, rp);
var randompoint = calculatingTargetPoints(point, bearing, distance);
var x = randompoint.longitude; //point.longitude + Math.random() * (bounds.west - bounds.east);
var y = randompoint.latitude; //point.latitude + Math.random() * (bounds.north - bounds.south);
var value = Math.random() * 100;
data.push({
x: x,
y: y,
value: value
});
}
return data;
}
是动态效果,截图是静态,可以自己运行试试
5、少个函数,补充
//计算一个点周围某一方向,某一距离上的点
function calculatingTargetPoints(pos, direction, radius) {
// 观察点
var viewPoint = Cesium.Cartesian3.fromDegrees(pos.longitude, pos.latitude, pos.height);
// 世界坐标转换为投影坐标
var webMercatorProjection = new Cesium.WebMercatorProjection(viewer.scene.globe.ellipsoid);
var viewPointWebMercator = webMercatorProjection.project(Cesium.Cartographic.fromCartesian(viewPoint));
// 计算目标点
var toPoint = new Cesium.Cartesian3(viewPointWebMercator.x + radius * Math.cos(direction), viewPointWebMercator.y +
radius * Math.sin(direction), 0);
// 投影坐标转世界坐标
toPoint = webMercatorProjection.unproject(toPoint);
toPoint = Cesium.Cartographic.toCartesian(toPoint.clone());
// 世界坐标转地理坐标
var cartographic = Cesium.Cartographic.fromCartesian(toPoint);
var point = {
longitude: Cesium.Math.toDegrees(cartographic.longitude),
latitude: Cesium.Math.toDegrees(cartographic.latitude),
height: cartographic.height
}
return point;
}
最后感谢阅读,如有不足指出,请指正,谢谢。