1、创建mapFunction.js文件
export class mapFunction {
constructor(viewer, Cesium) {
this.viewer = viewer
this.Cesium = Cesium
}
// 根据ID查询Entity模型
/**
* 函数用途:根据ID查询Entity模型
* 参数注释:
* @param {String} id - 模型ID
* @returns Entity实体 - 返回查询结果
*/
findEntityById(id) {
let entity = this.viewer.entities.getById(id);
return entity
}
/**
* 函数用途:根据ID删除Entity模型
* 参数注释:
* @param {String} id - 模型ID
*/
removeEntityById(id) {
let entity = this.viewer.entities.getById(id);
if (entity) {
this.viewer.entities.remove(entity);
}
}
/**
* 函数用途:根据名称查询entity模型
* 参数注释:
* @param {String} name - 模型名称
* @returns Array[Entity实体] - 返回查询结果
*/
findEntityByName(name) {
let entities = this.viewer.entities.values;
let temp = [];
for (let item of entities) {
if (item._name == name) {
temp.push(i);
}
}
return temp;
}
/**
* 函数用途:查询所有Entity模型
* 参数注释:无参
* @returns Array[Entity实体] - 返回查询结果
*/
findAllEntity() {
let entities = this.viewer.entities.values;
return entities
}
/**
* 函数用途:查询所有primitive模型
* 参数注释:无参
* @returns Array[primitive实体] - 返回查询结果
*/
findAllPrimitive() {
let primitives = this.viewer.scene.primitives._primitives
return primitives
}
/**
* 函数用途:删除所有Entity模型
* 参数注释:无参
*/
removeAllEntity() {
this.viewer.entities.removeAll();
}
/**
* 函数用途:删除所有Primitive模型
* 参数注释:无参
*/
removeAllPrimitive() {
let primitives = this.viewer.scene.primitives._primitives;
for (let i = 0; i < primitives.length; i++) {
if (primitives[i].geometryInstances) {
this.viewer.scene.primitives.remove(primitives[i]);
i--;
}
}
}
/**
* 函数用途:屏幕坐标转经纬坐标
* 参数注释:
* @param {Number} x - x轴坐标
* @param {Number} y - y轴坐标
* @param {Number} height - 高度
* @returns Object{经度,纬度,高度} - 返回转换结果
*/
convertScreen(x, y, height = 0) {
// 屏幕坐标转换为二维笛卡尔坐标
let cartesianCoordinate = new this.Cesium.Cartesian2(x, y);
// 获取二维笛卡尔的对应椭球面位置
let wordCoordinate = this.viewer.scene.camera.pickEllipsoid(
cartesianCoordinate,
this.viewer.scene.globe.ellipsoid
);
// 笛卡尔坐标转弧度
let cartographic = this.Cesium.Cartographic.fromCartesian(
wordCoordinate,
this.viewer.scene.globe.ellipsoid,
new this.Cesium.Cartographic()
);
// Cesium.Math.toDegrees 将弧度转换成经纬度
let longitude = this.Cesium.Math.toDegrees(cartographic.longitude); // 经度
let latitude = this.Cesium.Math.toDegrees(cartographic.latitude); // 纬度
return {
longitude,
latitude,
height,
};
}
/**
* 函数用途:世界坐标转经纬度
* 参数注释:
* @param {Number} x - x轴坐标
* @param {Number} y - y轴坐标
* @param {Number} z - z轴坐标
* @returns Object{经度,纬度,高度} - 返回转换结果
*/
convertWord(x, y, z) {
let cartographic = this.Cesium.Ellipsoid.WGS84.cartesianToCartographic({
x,
y,
z,
});
let longitude = this.Cesium.Math.toDegrees(cartographic.longitude); // 经度
let latitude = this.Cesium.Math.toDegrees(cartographic.latitude); // 纬度
let height = cartographic.height; // 高度
return {
longitude,
latitude,
height
};
}
/**
* 函数用途:使用Turf.js计算两点之间的距离
* 参数注释:
* @param {Object} turf - Turf.js库对象
* @param {Number} lastDistance - 上一次计算结果
* @param {Array<Number>} startPoint - 起始点:[经度,纬度]
* @param {Array<Number>} endPoint - 结束点:[经度,纬度]
* @param {String} units - 单位
* @returns Number - 返回计算结果
*/
countDistance(turf, lastDistance, startPoint, endPoint, units = "kilometers") {
// 计算距离
lastDistance += turf.distance(
turf.point(startPoint),
turf.point(endPoint),
{ units }
);
return lastDistance
}
/**
* 函数用途:使用Turf.js计算区域中心点(最后一个点需要和第一个点相同)
* @param {Object} turf - Turf.js库对象
* @param {Array<Array<Number>>} points - 区域坐标集合:[[经度,纬度],[经度,纬度]......]
* @returns Object{经度,纬度} - 返回计算结果
*/
countCenter(turf, points) {
// 计算中心点
let pointArray = turf.polygon([points]);
let center = turf.centerOfMass(pointArray);
let longitude = center.geometry.coordinates[0];
let latitude = center.geometry.coordinates[1];
// 计算多边形的中心点
return { longitude, latitude };
}
/**
* 函数用途:使用Turf.js计算区域面积(最后一个点需要和第一个点相同)
* @param {Object} turf - Turf.js库对象
* @param {Array<Array<Number>>} points - 区域坐标集合:[[经度,纬度],[经度,纬度]......]
* @param {Number} num - 默认保留6位小数
* @returns Number - 返回计算结果
*/
countArea(turf, points, num = 6) {
let pointArray = turf.polygon([points]);
// 计算多边形面积,默认为平方米,转换为平方公里(除以1000000)
let area = Number((turf.area(pointArray) / 1000000).toFixed(num));
return area
}
/**
* 函数用途:计算以中间点为顶点的三个点形成的夹角角度
* @param {Array<Object>} points - 参与计算的点:[{经度,纬度},{经度,纬度},{经度,纬度}]
* @returns Number - 返回计算结果(0 - 180)
*/
countAngle(points) {
// 将经纬度转换为笛卡尔坐标
const cartesian1 = this.Cesium.Cartesian3.fromDegrees(
points[0].longitude, points[0].latitude
);
const cartesian2 = this.Cesium.Cartesian3.fromDegrees(
points[1].longitude, points[1].latitude
);
const cartesian3 = this.Cesium.Cartesian3.fromDegrees(
points[2].longitude, points[2].latitude
);
// 构造向量(从顶点point2指向point1和point3)
const vec1 = this.Cesium.Cartesian3.subtract(
cartesian1,
cartesian2,
new this.Cesium.Cartesian3()
);
const vec2 = this.Cesium.Cartesian3.subtract(
cartesian3,
cartesian2,
new this.Cesium.Cartesian3()
);
// 归一化向量(单位向量)
this.Cesium.Cartesian3.normalize(vec1, vec1);
this.Cesium.Cartesian3.normalize(vec2, vec2);
// 计算点积
const dot = this.Cesium.Cartesian3.dot(vec1, vec2);
// 处理浮点误差(确保值在[-1, 1]范围内)
const clampedDot = Math.min(Math.max(dot, -1.0), 1.0);
// 计算夹角(弧度转角度)
const angleRad = Math.acos(clampedDot);
return this.Cesium.Math.toDegrees(angleRad);
}
/**
* 函数用途:计算起始点到结束点的方位角
* @param {Object} turf - Turf.js库对象
* @param {Object} startPoint - 起始点:{经度,纬度}
* @param {Object} endPoint - 结束点:{经度,纬度}
* @returns Number - 返回计算结果
*/
countAzimuthAngle(turf, startPoint, endPoint) {
// 计算方位角度
let bearing = turf.rhumbBearing(
[startPoint.longitude, startPoint.latitude],
[endPoint.longitude, endPoint.latitude]
);
return bearing
}
/**
* 函数用途:设置相机视角-瞬间定位
* @param {Object} param0 - 相机坐标:{经度,纬度,高度}
* @param {Object} param1 - 相机视角:{水平旋转角度,俯仰角度,翻滚角度}
*/
cameraSetView({ longitude, latitude, height }, { heading = 0, pitch = -90, roll = 0 }) {
this.viewer.scene.camera.setView({
destination: this.Cesium.Cartesian3.fromDegrees(
longitude,
latitude,
height
),
orientation: {
heading: this.Cesium.Math.toRadians(heading),
pitch: this.Cesium.Math.toRadians(pitch),
roll,
},
});
}
/**
* 函数用途:设置相机视角-飞行过渡定位
* @param {Object} param0 - 相机坐标:{经度,纬度,高度}
* @param {Object} param1 - 相机视角:{水平旋转角度,俯仰角度,翻滚角度}
* @param {Number} duration - 飞行时间
* @param {Function} callback - 飞行完成的回到函数
*/
cameraFlyTo({ longitude, latitude, height }, { heading = 0, pitch = -90, roll = 0 }, duration = 5, callback) {
this.viewer.camera.flyTo({
destination: this.Cesium.Cartesian3.fromDegrees(
longitude,
latitude,
height
),
orientation: {
heading: this.Cesium.Math.toRadians(heading),
pitch: this.Cesium.Math.toRadians(pitch),
roll,
},
duration, // 飞行时间(秒)
complete: callback ? callback : () => { console.log("到达") } // 回调函数
});
}
/**
* 函数用途:设置地图图层
* @param {String} url - 图层地址
*/
switchLayers(url) {
if (this.viewer.imageryLayers.length > 0) {
this.viewer.imageryLayers.remove(this.viewer.imageryLayers.get(0));
}
this.viewer.imageryLayers.addImageryProvider(
new this.Cesium.UrlTemplateImageryProvider({
url,
})
);
}
/**
* 函数用途:左键单击监听事件
* @param {Function} callback - 监听回调函数
*/
leftClick(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
/**
* 函数用途:左键双击监听事件
* @param {Function} callback - 监听回调函数
*/
leftDouBleClick(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
}
/**
* 函数用途:左键按下监听事件
* @param {Function} callback - 监听回调函数
*/
leftDown(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.LEFT_DOWN);
}
/**
* 函数用途:左键抬起监听事件
* @param {Function} callback - 监听回调函数
*/
leftUp(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.LEFT_UP);
}
/**
* 函数用途:中键单击监听事件
* @param {Function} callback - 监听回调函数
*/
middleClick(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.MIDDLE_CLICK);
}
/**
* 函数用途:中键按下监听事件
* @param {Function} callback - 监听回调函数
*/
middleDown(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.MIDDLE_DOWN);
}
/**
* 函数用途:中键抬起监听事件
* @param {Function} callback - 监听回调函数
*/
middleUp(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.MIDDLE_UP);
}
/**
* 函数用途:右键单击监听事件
* @param {Function} callback - 监听回调函数
*/
rightClick(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
/**
* 函数用途:右键按下监听事件
* @param {Function} callback - 监听回调函数
*/
rightDown(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.RIGHT_DOWN);
}
/**
* 函数用途:右键抬起监听事件
* @param {Function} callback - 监听回调函数
*/
rightUp(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.RIGHT_UP);
}
/**
* 函数用途:鼠标移动监听事件
* @param {Function} callback - 监听回调函数
*/
mouseMove(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
/**
* 函数用途:鼠标滚轮监听事件
* @param {Function} callback - 监听回调函数
*/
mouseWheel(callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType.WHEEL);
}
/**
* 函数用途:鼠标事件监听
* @param {String} type - 事件类型:LEFT_CLICK、LEFT_DOUBLE_CLICK、......
* @param {Function} callback - 监听回调函数
*/
mouseListen(type, callback) {
// 添加用户输入监听范围(element)
let handler = new this.Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 处理用户输入事件
handler.setInputAction((event) => {
callback(event)
}, this.Cesium.ScreenSpaceEventType[type]);
}
/**
* 函数用途:移除鼠标事件监听
* @param {String} type - 事件类型:LEFT_CLICK、LEFT_DOUBLE_CLICK、......
*/
removeMouseListen(type) {
this.viewer.screenSpaceEventHandler.removeInputAction(
this.Cesium.ScreenSpaceEventType[type]
);
}
}
2、组件应用
<script setup>
import { mapFunction } from './mapFunction'
const mapFun = new mapFunction(viewer,Cesium)
// 示例一:根据ID查询Entity模型
mapFun.findEntityById(<model_id>)
// 示例二:根据ID删除Entity模型
mapFun.removeEntityById(<model_id>)
// 示例三:根据名称查询entity模型
mapFun.findEntityByName(<model_name>)
......
</script>