初始化仓库

This commit is contained in:
yiqiuyang
2025-09-10 00:13:57 +08:00
commit 17180ec339
417 changed files with 285450 additions and 0 deletions

View File

@ -0,0 +1,647 @@
/**
* Mars3D平台插件,结合heatmap可视化功能插件 mars3d-heatmap
*
* 版本信息v3.4.7
* 编译日期2022-09-15 16:25:35
* 版权所有Copyright by 火星科技 http://mars3d.cn
* 使用单位安徽XX有限公司 2021-08-18
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, (window.mars3d || require('mars3d')), (window.h337 || require('@mars3d/heatmap.js'))) :
typeof define === 'function' && define.amd ? define(['exports', 'mars3d', '@mars3d/heatmap.js'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["mars3d-heatmap"] = {}, global.mars3d, global.h337));
})(this, (function (exports, mars3d, h337) { 'use strict';
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return n;
}
var mars3d__namespace = /*#__PURE__*/_interopNamespace(mars3d);
var h337__namespace = /*#__PURE__*/_interopNamespace(h337);
var HeatMaterial = "uniform sampler2D image;\n\nczm_material czm_getMaterial(czm_materialInput materialInput) {\n czm_material material = czm_getDefaultMaterial(materialInput);\n vec2 st = materialInput.st;\n vec4 colorImage = texture2D(image, st);\n if(colorImage.rgb == vec3(1.0) || colorImage.rgb == vec3(0.0)) {\n discard;\n }\n material.diffuse = colorImage.rgb;\n material.alpha = colorImage.a;\n return material;\n}\n"; // eslint-disable-line
if (!h337__namespace.create) {
throw new Error("请引入 heatmap.js 库 ")
}
const Cesium = mars3d__namespace.Cesium;
const BaseLayer = mars3d__namespace.layer.BaseLayer;
// 热力图默认参数
const DEF_HEATSTYLE = {
maxOpacity: 0.8,
minOpacity: 0.1,
blur: 0.85,
radius: 25,
gradient: {
0.4: "blue",
0.6: "green",
0.8: "yellow",
0.9: "red"
}
};
const DEF_STYLE = {
arcRadiusScale: 1.5,
arcBlurScale: 1.5,
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT
};
/**
* 热力图图层基于heatmap.js库渲染。
* 【需要引入 heatmap.js 库 和 mars3d-heatmap 插件库】
*
* @param {Object} options 参数对象,包括以下:
* @param {LngLatPoint[]|Cesium.Cartesian3[]|Object[]} [options.positions] 坐标数据集合含value热力值有热力值时传入LatLngPoint数组热力值为value字段。示例:[{lat:31.123,lng:103.568,value:1.2},{lat:31.233,lng:103.938,value:2.3}]
*
* @param {Object} [options.rectangle] 坐标的矩形区域范围,默认内部自动计算
* @param {Number} options.rectangle.xmin 最小经度值
* @param {Number} options.rectangle.xmax 最大经度值
* @param {Number} options.rectangle.ymin 最小纬度值
* @param {Number} options.rectangle.ymax 最大纬度值
*
* @param {Number} [options.max] 数据集的value值上限默认内部计算
* @param {Number} [options.min] 数据集的value值下限默认内部计算
*
* @param {Object} [options.heatStyle] heatmap热力图本身configObject参数详情也可查阅 [heatmap文档]{@link https://www.patrick-wied.at/static/heatmapjs/docs.html}
* @param {Number} [options.heatStyle.maxOpacity=0.8] 最大不透明度取值范围0.0-1.0。
* @param {Number} [options.heatStyle.minOpacity=0.1] 最小不透明度取值范围0.0-1.0。
* @param {Number} [options.heatStyle.blur=0.85] 将应用于所有数据点的模糊因子。模糊因子越高,渐变将越平滑
* @param {Number} [options.heatStyle.radius=25] 每个数据点将具有的半径(如果未在数据点本身上指定)
* @param {Object} [options.heatStyle.gradient] 色带,表示渐变的对象,示例:{ 0.4: 'blue', 0.6: 'green',0.8: 'yellow',0.9: 'red' }
*
* @param {RectanglePrimitive.StyleOptions|Object} [options.style] 矢量对象样式参数,还包括:
* @param {Boolean} [options.style.opacity=1] 透明度
* @param {Boolean} [options.style.arc=false] 是否显示曲面热力图
* @param {Boolean} [options.style.arcRadiusScale=1.5] 曲面热力图时radius扩大比例
* @param {Boolean} [options.style.arcBlurScale=1.5] 曲面热力图时blur扩大比例
* @param {Number} [options.style.height = 0] 高度,相对于椭球面的高度。
* @param {Number} [options.style.diffHeight ] 曲面的起伏差值高,默认根据数据范围的比例自动计算。
* @param {RectanglePrimitive.StyleOptions} [options.style.多个参数] rectangle矩形支持的样式
*
* @param {Number} [options.maxCanvasSize=5000] Canvas最大尺寸单位像素调大精度更高但过大容易内存溢出
* @param {Number} [options.minCanvasSize=700] Canvas最小尺寸单位像素
* @param {Number} [options.delayTime=2] 显示数据时的过渡动画时长(单位:秒)
*
* @param {String|Number} [options.id = createGuid()] 图层id标识
* @param {String|Number} [options.pid = -1] 图层父级的id一般图层管理中使用
* @param {String} [options.name = ''] 图层名称
* @param {Boolean} [options.show = true] 图层是否显示
* @param {BaseClass|Boolean} [options.eventParent] 指定的事件冒泡对象默认为map对象false时不冒泡
* @param {Object} [options.center] 图层自定义定位视角 {@link Map#setCameraView}
* @param {Number} options.center.lng 经度值, 180 - 180
* @param {Number} options.center.lat 纬度值, -90 - 90
* @param {Number} [options.center.alt] 高度值
* @param {Number} [options.center.heading] 方向角度值,绕垂直于地心的轴旋转角度, 0至360
* @param {Number} [options.center.pitch] 俯仰角度值,绕纬度线旋转角度, -90至90
* @param {Number} [options.center.roll] 翻滚角度值,绕经度线旋转角度, -90至90
* @param {Boolean} [options.flyTo] 加载完成数据后是否自动飞行定位到数据所在的区域。
* @export
* @class HeatLayer
* @extends {BaseLayer}
*/
class HeatLayer extends BaseLayer {
constructor(options = {}) {
super(options);
this.options.maxCanvasSize = this.options.maxCanvasSize ?? document.body.clientWidth;
this.options.maxCanvasSize = Math.min(this.options.maxCanvasSize, 5000);
this.options.minCanvasSize = this.options.minCanvasSize ?? document.body.clientHeight;
this.options.minCanvasSize = Math.max(this.options.minCanvasSize, 700);
this.options.heatStyle = {
...DEF_HEATSTYLE,
...(this.options.heatStyle || {})
};
this.options.style = {
...DEF_STYLE,
...(this.options.style || {})
};
}
/**
* 矢量数据图层
* @type {GraphicLayer}
* @readonly
*/
get layer() {
return this._layer
}
/**
* heatmap热力图本身configObject参数详情也可查阅 [heatmap文档]{@link https://www.patrick-wied.at/static/heatmapjs/docs.html}
* @type {Object}
*/
get heatStyle() {
return this.options.heatStyle
}
set heatStyle(value) {
this.options.heatStyle = mars3d__namespace.Util.merge(this.options.heatStyle, value);
if (this._heat) {
this._heat.configure(this.options.heatStyle);
this._updatePositionsHook(true);
}
}
/**
* 矩形的样式参数
* @type {RectanglePrimitive.StyleOptions}
*/
get style() {
return this.options.style
}
set style(value) {
this.options.style = mars3d__namespace.Util.merge(this.options.style, value);
}
/**
* 坐标数据集合含value热力值示例:[{lat:31.123,lng:103.568,value:1.2},{lat:31.233,lng:103.938,value:2.3}] 。
* 平滑更新建议使用setPositions方法
* @type {Cesium.Cartesian3[]|LngLatPoint[]}
*/
get positions() {
return this._positions
}
set positions(value) {
this.setPositions(value);
}
/**
* 位置坐标(数组对象),示例 [ [123.123456,32.654321,198.7], [111.123456,22.654321,50.7] ]
* @type {Array[]}
* @readonly
*/
get coordinates() {
const coords = [];
this.points.forEach((item) => {
coords.push(item.toArray());
});
return coords
}
/**
* 坐标数据对应的矩形边界
* @type {Cesium.Rectangle}
* @readonly
*/
get rectangle() {
return this._rectangle
}
_setOptionsHook(options, newOptions) {
if (options.positions) {
this.positions = options.positions;
}
}
/**
* 对象添加到地图前创建一些对象的钩子方法,
* 只会调用一次
* @return {void} 无
* @private
*/
_mountedHook() {
this._layer = new mars3d__namespace.layer.GraphicLayer({
private: true
});
}
/**
* 对象添加到地图上的创建钩子方法,
* 每次add时都会调用
* @return {void} 无
* @private
*/
_addedHook() {
this._map.addLayer(this._layer);
if (this.options.positions) {
this.positions = this.options.positions;
}
if (this.options.flyTo) {
this.flyToByAnimationEnd();
}
}
/**
* 对象从地图上移除的创建钩子方法,
* 每次remove时都会调用
* @return {void} 无
* @private
*/
_removedHook() {
if (this.heatStyle.container) {
mars3d__namespace.DomUtil.remove(this.heatStyle.container);
delete this.heatStyle.container;
}
this.clear();
this._map.removeLayer(this._layer);
}
/**
* 添加新的坐标点(含热力值)
* @param {Cesium.Cartesian3 |LngLatPoint} item 坐标点(含热力值),示例: {lat:31.123,lng:103.568,value:1.2}
* @param {Boolean} [isGD] 是否固定区域坐标true时可以平滑更新
* @return {void} 无
*/
addPosition(item, isGD) {
this._positions = this._positions || [];
this._positions.push(item);
this._updatePositionsHook(isGD);
}
/**
* 更新所有坐标点(含热力值)数据
*
* @param {Cesium.Cartesian3[] |LngLatPoint[]} arr 坐标点(含热力值),示例:[{lat:31.123,lng:103.568,value:1.2},{lat:31.233,lng:103.938,value:2.3}]
* @param {Boolean} [isGD] 是否固定区域坐标true时可以平滑更新
* @return {void} 无
*/
setPositions(arr, isGD) {
this._positions = arr;
this._updatePositionsHook(isGD);
}
/**
* 清除矢量对象
* @return {void} 无
*/
clear() {
if (this._graphic) {
this._layer.removeGraphic(this._graphic, true);
delete this._graphic;
}
}
_updatePositionsHook(isGD) {
if (!this.show || !this._map || !this.positions || this.positions.length === 0) {
return this
}
const canvas = this._getHeatCanvas();
if (this.style.arc) {
if (this._graphic && isGD) {
this._graphic.uniforms.image = canvas;
this._graphic.uniforms.bumpMap = this._getArcHeatCanvas();
} else {
this._createArcGraphic(canvas);
}
} else {
if (this._graphic && isGD) {
this._graphic.uniforms.image = canvas;
} else {
this._createGraphic(canvas);
}
}
return this
}
// 普通平面热力图
_createGraphic(image) {
this.clear();
this._graphic = new mars3d__namespace.graphic.RectanglePrimitive({
...this.options,
rectangle: this._rectangle,
appearance: new Cesium.EllipsoidSurfaceAppearance({
material: new Cesium.Material({
fabric: {
uniforms: {
image: image
},
source: HeatMaterial
},
translucent: true
}),
flat: true
})
});
this._layer.addGraphic(this._graphic);
}
// 曲面 热力图
_createArcGraphic(canvas) {
this.clear();
const renderstate = Cesium.RenderState.fromCache({
cull: {
enabled: true
},
depthTest: {
enabled: true
},
stencilTest: {
enabled: true,
frontFunction: Cesium.StencilFunction.ALWAYS,
frontOperation: {
fail: Cesium.StencilOperation.KEEP,
zFail: Cesium.StencilOperation.KEEP,
zPass: Cesium.StencilOperation.REPLACE
},
backFunction: Cesium.StencilFunction.ALWAYS,
backOperation: {
fail: Cesium.StencilOperation.KEEP,
zFail: Cesium.StencilOperation.KEEP,
zPass: Cesium.StencilOperation.REPLACE
},
reference: 0x2,
mask: 0x2
},
blending: Cesium.BlendingState.ALPHA_BLEND
});
// 曲面的起伏差值高
const diffHeight = Math.floor(this.style.diffHeight ?? this._mBoundsMax * 0.02) + 0.1;
if (this.style.diffHeight) {
delete this.style.diffHeight;
}
// 控制曲面的精度
const splitNum = (this.style.splitNum, 100);
let granularity = Math.max(this._rectangle.height, this._rectangle.width);
this.style.granularity = granularity /= splitNum;
// console.log(this.options.style.granularity)
this._graphic = new mars3d__namespace.graphic.RectanglePrimitive({
...this.options,
rectangle: this._rectangle,
appearance: new Cesium.EllipsoidSurfaceAppearance({
aboveGround: true,
renderState: renderstate,
material: new Cesium.Material({
fabric: {
uniforms: {
image: canvas,
repeat: new Cesium.Cartesian2(1.0, 1.0),
color: new Cesium.Color(1.0, 1.0, 1.0, 0.01),
bumpMap: this._getArcHeatCanvas()
},
source: HeatMaterial
},
translucent: true
}),
vertexShaderSource: `attribute vec3 position3DHigh;
attribute vec3 position3DLow;
attribute vec2 st;
attribute float batchId;
uniform sampler2D bumpMap_3;
varying vec3 v_positionMC;
varying vec3 v_positionEC;
varying vec2 v_st;
void main()
{
vec4 p = czm_computePosition();
v_positionMC = position3DHigh + position3DLow;
v_positionEC = (czm_modelViewRelativeToEye * p).xyz;
v_st = st;
vec4 color = texture2D(bumpMap_3, v_st);
float centerBump = distance(vec3(0.0),color.rgb);
vec3 upDir = normalize(v_positionMC.xyz);
vec3 disPos = upDir * centerBump * ${diffHeight};
p +=vec4(disPos,0.0);
gl_Position = czm_modelViewProjectionRelativeToEye * p;
}
`,
flat: true
})
});
this._layer.addGraphic(this._graphic);
}
/**
* 获取图层内所有数据的 矩形边界值
* @param {Boolean} [options] 控制参数
* @param {Boolean} [options.isFormat=false] 是否格式化,格式化时示例: { xmin: 73.16895, xmax: 134.86816, ymin: 12.2023, ymax: 54.11485 }
* @return {Cesium.Rectangle|Object} isFormattrue时返回格式化对象isFormatfalse时返回Cesium.Rectangle对象
*/
getRectangle(options) {
if (options?.isFormat && this._rectangle) {
return mars3d__namespace.PolyUtil.formatRectangle(this._rectangle)
} else {
return this._rectangle
}
}
// 处理数据并返回生成的图片
_getHeatCanvas() {
const positions = this._positions;
const _points = [];
let xmin, xmax, ymin, ymax;
positions.forEach((item) => {
const point = mars3d__namespace.LngLatPoint.parse(item);
if (!point) {
return
}
point.value = item.value || 1; // 热力值
if (!this.options.rectangle) {
if (xmin === undefined) {
xmin = point.lng;
xmax = point.lng;
ymin = point.lat;
ymax = point.lat;
} else {
xmin = Math.min(xmin, point.lng);
xmax = Math.max(xmax, point.lng);
ymin = Math.min(ymin, point.lat);
ymax = Math.max(ymax, point.lat);
}
}
_points.push(point);
});
// 经纬度边界
let _bounds = this.options.rectangle || { xmin, xmax, ymin, ymax };
// 墨卡托边界值
const mBounds = getMercatorBounds(_bounds);
// 计算范围内的差值和极值
const diffLng = Math.abs(mBounds.xmax - mBounds.xmin);
const diffLat = Math.abs(mBounds.ymax - mBounds.ymin);
const max = Math.max(diffLng, diffLat);
const min = Math.min(diffLng, diffLat);
this._mBoundsMax = max;
// 计算是否缩放
let scale = 1;
if (max > this.options.maxCanvasSize) {
scale = max / this.options.maxCanvasSize;
if (min / scale < this.options.minCanvasSize) {
scale = min / this.options.minCanvasSize;
}
} else if (min < this.options.minCanvasSize) {
scale = min / this.options.minCanvasSize;
if (max / scale > this.options.maxCanvasSize) {
scale = max / this.options.maxCanvasSize;
}
}
const spacing = this.heatStyle.radius * 1.5;
const canvasWidth = diffLng / scale + spacing * 2;
const canvasHeight = diffLat / scale + spacing * 2;
const offset = spacing * scale;
mBounds.xmin -= offset;
mBounds.ymin -= offset;
mBounds.xmax += offset;
mBounds.ymax += offset;
this._scale = scale;
// 加扩大值后的边界
_bounds = geLatLngBounds(mBounds);
this._rectangle = Cesium.Rectangle.fromDegrees(_bounds.xmin, _bounds.ymin, _bounds.xmax, _bounds.ymax);
let maxVal = _points[0].value ?? 1;
let minVal = _points[0].value ?? 0;
const hetdata = [];
_points.forEach((point) => {
const mkt = mars3d__namespace.PointTrans.lonlat2mercator([point.lng, point.lat]);
const value = point.value || 1;
const coord_x = Math.round((mkt[0] - mBounds.xmin) / scale);
const coord_y = Math.round((mBounds.ymax - mkt[1]) / scale);
maxVal = Math.max(maxVal, value); // 求最大值
minVal = Math.min(minVal, value);
hetdata.push({
x: coord_x,
y: coord_y,
value: value
});
});
const heatData = {
min: this.options.min ?? minVal,
max: this.options.max ?? maxVal,
data: hetdata
};
this._last_heatData = heatData;
if (
!this._last_mBounds ||
mBounds.xmin !== this._last_mBounds.xmin ||
mBounds.ymin !== this._last_mBounds.ymin ||
mBounds.xmax !== this._last_mBounds.xmax ||
mBounds.ymax !== this._last_mBounds.ymax
) {
this._last_mBounds = mBounds;
if (!this.heatStyle.container) {
this.heatStyle.container = mars3d__namespace.DomUtil.create("div", "mars3d-heatmap mars3d-hideDiv", this._map.container);
}
this.heatStyle.container.style.cssText = `width:${canvasWidth}px;height:${canvasHeight}px;`;
if (!this._heat) {
this._heat = h337__namespace.create(this.heatStyle);
} else {
this._heat.configure(this.heatStyle);
}
}
this._heat.setData(heatData);
const canvas = mars3d__namespace.DomUtil.copyCanvas(this._heat._renderer.canvas);
// 注释不删除,便于动态更新
// if (this.heatStyle.container) {
// mars3d.DomUtil.remove(this.heatStyle.container)
// delete this.heatStyle.container
// }
return canvas
}
_getArcHeatCanvas() {
this._heat.configure({
radius: this.heatStyle.radius * this.style.arcRadiusScale,
blur: this.heatStyle.blur * this.style.arcBlurScale,
gradient: this.heatStyle.gradientArc || {
0.25: "rgb(0,0,0)",
0.55: "rgb(140,140,140)",
0.85: "rgb(216,216,216)",
1.0: "rgb(255,255,255)"
}
});
const canvasBump = mars3d__namespace.DomUtil.copyCanvas(this._heat._renderer.canvas);
this._heat.configure(this.options.heatStyle); // 恢复配置
return canvasBump
}
/**
* 根据坐标点获取其对应的value值和颜色值
* @param {Cesium.Cartesian3 |LngLatPoint} item 坐标点
* @return {Object} 格式为 {"x":2081,"y":767,"value":3,"color":"rgba(209,231,0,195)"}
*/
getPointData(item) {
const point = mars3d__namespace.LngLatPoint.parse(item);
if (!point) {
return {}
}
const mkt = mars3d__namespace.PointTrans.lonlat2mercator([point.lng, point.lat]);
const mBounds = this._last_mBounds;
const coord_x = Math.round((mkt[0] - mBounds.xmin) / this._scale);
const coord_y = Math.round((mBounds.ymax - mkt[1]) / this._scale);
const value = this._heat.getValueAt({ x: coord_x, y: coord_y });
const rgba = this._heat._renderer.ctx.getImageData(coord_x - 1, coord_y - 1, 1, 1).data;
return {
x: coord_x,
y: coord_y,
value: value,
color: "rgba(" + rgba[0] + "," + rgba[1] + "," + rgba[2] + "," + rgba[3] + ")"
}
}
}
mars3d__namespace.layer.HeatLayer = HeatLayer;
mars3d__namespace.LayerUtil.register("heat", HeatLayer);
function getMercatorBounds(bounds) {
const pt1 = mars3d__namespace.PointTrans.lonlat2mercator([bounds.xmin, bounds.ymin]);
const pt2 = mars3d__namespace.PointTrans.lonlat2mercator([bounds.xmax, bounds.ymax]);
return { xmin: pt1[0], ymin: pt1[1], xmax: pt2[0], ymax: pt2[1] }
}
function geLatLngBounds(bounds) {
const pt1 = mars3d__namespace.PointTrans.mercator2lonlat([bounds.xmin, bounds.ymin]);
const pt2 = mars3d__namespace.PointTrans.mercator2lonlat([bounds.xmax, bounds.ymax]);
return { xmin: pt1[0], ymin: pt1[1], xmax: pt2[0], ymax: pt2[1] }
}
exports.HeatLayer = HeatLayer;
Object.defineProperty(exports, '__esModule', { value: true });
}));

File diff suppressed because one or more lines are too long