小封一下,文件名usePublic.js
import * as Cesium from "cesium";
// import * as turf from '@turf/turf'
// let Cesium = window.Cesium
var cesiumPublic = {
viewer: null,
handler: null,
init: function (viewer) {
if (viewer) {
this.viewer = viewer
}
},
// 绘制点
drawPoint: function (whetherStart) {
let viewer = this.viewer
let that = this
return new Promise((resolve, reject) => {
if (viewer) {
if (whetherStart) {
// 清除以前的点
that.removeEntityByName('drawPoint')
// 鼠标移动,绘制动态点
viewer.screenSpaceEventHandler.setInputAction(function (movement) {
const newPosition = viewer.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);//当前世界坐标笛卡尔积
if (Cesium.defined(newPosition)) {
// 清除移动点
that.removeEntityByName('movePoint')
// 绘制移动点
viewer.entities.add({
name: 'movePoint',
position: newPosition,
point: new Cesium.PointGraphics({
show: true,
pixelSize: 15,
heightReference: Cesium.HeightReference.NONE,
color: Cesium.Color.fromBytes(30, 144, 255),
outlineColor: new Cesium.Color(0, 0, 0, 0),
outlineWidth: 0,
})
});
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 鼠标左键绘制最终点
viewer.screenSpaceEventHandler.setInputAction(function (movement) {
const earthPosition = viewer.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);//当前世界坐标笛卡尔积
if (Cesium.defined(earthPosition)) {
// 清除移动点
that.removeEntityByName('movePoint')
viewer.entities.add({
name: 'drawPoint',
position: earthPosition,
point: new Cesium.PointGraphics({
show: true,
pixelSize: 15,
heightReference: Cesium.HeightReference.NONE,
color: Cesium.Color.fromBytes(139, 0, 0),
outlineColor: new Cesium.Color(0, 0, 0, 0),
outlineWidth: 0,
})
});
// 世界坐标转换为经纬度
const carto_position = Cesium.Cartographic.fromCartesian(earthPosition);
const longitude = Cesium.Math.toDegrees(carto_position.longitude).toFixed(3);//四舍五入保留三位小数
const latitude = Cesium.Math.toDegrees(carto_position.latitude).toFixed(3);
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);//停止监听移动事件
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);//停止监听移动事件
const data = { longitude: longitude, latitude: latitude }
resolve(data)//返回经纬度
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
} else {
// 清除之前的实体
that.removeEntityByName('drawPoint')
that.removeEntityByName('movePoint')
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);//停止监听移动事件
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);//停止监听移动事件
}
}
})
},
/*
根据name删除实体
nameArray:实体名数组,
dim:是否模糊删除,默认false
*/
removeEntityByName: function (nameArray, dim) {
let viewer = this.viewer
// 清除之前的实体
const entitys = viewer.entities._entities._array;
let length = entitys.length
// 倒叙遍历防止实体减少之后entitys[f]不存在
for (let f = length - 1; f >= 0; f--) {
// if (entitys[f]._name && entitys[f]._name === value) {
// viewer.entities.remove(entitys[f]);
// }
nameArray.forEach(item => {
// 模糊删除
if (dim) {
if (entitys[f]._name && entitys[f]._name.indexOf(item) > -1) {
viewer.entities.remove(entitys[f]);
}
} else {//精准删除
if (entitys[f]._name && entitys[f]._name === item) {
viewer.entities.remove(entitys[f]);
}
}
})
}
},
/*
测距:左键单击开始,右键单击结束
entitiesName:实体名,非必传,建议传,可根据实体名删除实体
Promise返回最终距离
*/
range: function (entitiesName) {
entitiesName = entitiesName ? entitiesName : ''
let viewer = this.viewer
if (viewer) {
if (this.handler) {
this.handler.destroy(); //关闭事件句柄
this.handler = undefined;
}
return new Promise((resolve, reject) => {
// deleteRangeArea()
// 取消双击事件-追踪该位置
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
viewer.screenSpaceEventHandler.setInputAction(function () { }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
// viewer.trackedEntity = undefined;
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);
this.handler = handler
var positions = [];
var poly = null;
var distance = 0;
var cartesian = null;
var labelPt;
//鼠标移动事件
handler.setInputAction(function (movement) {
let ray = viewer.camera.getPickRay(movement.endPosition);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
if (!Cesium.defined(cartesian)) //跳出地球时异常
return;
if (positions.length >= 2) {
if (!Cesium.defined(poly)) {
//移动时路径绘制
poly = new PolyLinePrimitive(positions);
} else {
positions.pop();
positions.push(cartesian);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//鼠标左键点击事件
handler.setInputAction(function (movement) {
let ray = viewer.camera.getPickRay(movement.position);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
if (!Cesium.defined(cartesian)) //跳出地球时异常
return;
if (positions.length === 0) {
positions.push(cartesian.clone());
}
positions.push(cartesian);
//记录鼠标单击时的节点位置,异步计算贴地距离
labelPt = positions[positions.length - 1];
if (positions.length > 2) {
getSpaceDistance(positions);
} else if (positions.length === 2) {
//在三维场景中添加Label
viewer.entities.add({
name: entitiesName,
// id: "range",
position: labelPt,
point: {
pixelSize: 5,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
},
label: {
text: '起 点',
font: 'normal 8px SimHei',
fillColor: Cesium.Color.BLUE,
backgroundColor: Cesium.Color.WHITE, //背景颜色
//showBackground:true,
style: Cesium.LabelStyle.FILL, //label样式 FILL、OUTLINE、FILL_AND_OUTLINE
outlineWidth: 2,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,//水平位置
pixelOffset: new Cesium.Cartesian2(0, -10),
}
});
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
//鼠标左键双击事件,结束绘制
// handler.setInputAction(function (movement) {
// let ray = viewer.camera.getPickRay(movement.position);
// cartesian = viewer.scene.globe.pick(ray, viewer.scene);
// if (!Cesium.defined(cartesian)) //跳出地球时异常
// return;
// if (positions.length === 0) {
// positions.push(cartesian.clone());
// }
// positions.push(cartesian);
// //记录鼠标单击时的节点位置,异步计算贴地距离
// labelPt = positions[positions.length - 1];
// if (positions.length > 2) {
// getSpaceDistance(positions, true);
// } else if (positions.length === 2) {
// //在三维场景中添加Label
// viewer.entities.add({
// name: entitiesName,
// //id:"LEFT_DOUBLE_CLICK",
// position: labelPt,
// point: {
// pixelSize: 5,
// color: Cesium.Color.RED,
// outlineColor: Cesium.Color.WHITE,
// outlineWidth: 2,
// }
// });
// }
// handler.destroy(); //关闭事件句柄
// handler = undefined;
// }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
// 鼠标右键结束绘制
handler.setInputAction(function (movement) {
let ray = viewer.camera.getPickRay(movement.position);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
if (!Cesium.defined(cartesian)) //跳出地球时异常
return;
if (positions.length === 0) {
positions.push(cartesian.clone());
}
positions.push(cartesian);
//记录鼠标单击时的节点位置,异步计算贴地距离
labelPt = positions[positions.length - 1];
if (positions.length > 2) {
getSpaceDistance(positions, true);
} else if (positions.length === 2) {
//在三维场景中添加Label
viewer.entities.add({
name: entitiesName,
//id:"LEFT_DOUBLE_CLICK",
position: labelPt,
point: {
pixelSize: 5,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
}
});
}
handler.destroy(); //关闭事件句柄
handler = undefined;
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
var PolyLinePrimitive = (function () {
function _(positions) {
this.options = {
name: entitiesName,
polyline: {
show: true,
positions: [],
material: Cesium.Color.ORANGERED,
width: 3,
clampToGround: true
}
};
this.positions = positions;
this._init();
}
_.prototype._init = function () {
var _self = this;
var _update = function () {
return _self.positions;
};
//实时更新polyline.positions
this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
viewer.entities.add(this.options);
};
return _;
})();
//空间两点距离计算函数
function getSpaceDistance(positions, ifLast) {
//只计算最后一截,与前面累加
//因move和鼠标左击事件,最后两个点坐标重复
var i = positions.length - 3;
var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
getTerrainDistance(point1cartographic, point2cartographic, ifLast);
}
//贴地距离计算函数
function getTerrainDistance(point1cartographic, point2cartographic, ifLast) {
var geodesic = new Cesium.EllipsoidGeodesic();
geodesic.setEndPoints(point1cartographic, point2cartographic);
var s = geodesic.surfaceDistance;
var cartoPts = [point1cartographic];
for (var jj = 1000; jj < s; jj += 1000) {//分段采样计算距离
var cartoPt = geodesic.interpolateUsingSurfaceDistance(jj);
cartoPts.push(cartoPt);
}
cartoPts.push(point2cartographic);
//返回两点之间的距离
var promise = Cesium.sampleTerrain(viewer.terrainProvider, 2, cartoPts);
// 1.92版本后的 cesium 删除 Cesium.when ,使用原生promise,//本项目版本为1.104.0
promise.then((updatedPositions) => {
// 1.92版本前的用这个
// Cesium.when(promise, function (updatedPositions) {
for (var jj = 0; jj < updatedPositions.length - 1; jj++) {
var geoD = new Cesium.EllipsoidGeodesic();
geoD.setEndPoints(updatedPositions[jj], updatedPositions[jj + 1]);
var innerS = geoD.surfaceDistance;
innerS = Math.sqrt(Math.pow(innerS, 2) + Math.pow(updatedPositions[jj + 1].height - updatedPositions[jj].height, 2));
distance += innerS;
}
//在三维场景中添加Label
var textDisance = distance.toFixed(2) + "米";
if (distance > 10000)
textDisance = (distance / 1000.0).toFixed(2) + "千米";
if (ifLast) {//最后一个点则返回距离
resolve(textDisance)
}
viewer.entities.add({
name: entitiesName,
position: labelPt,
point: {
pixelSize: 4,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
},
label: {
text: textDisance,
font: '14px sans-serif',
// font: 'normal 14px SimHei',
fillColor: Cesium.Color.WHITE,//获取或设置此标签的填充颜色。
showBackground: true,//是否显示背景颜色
// backgroundColor: Cesium.Color.fromCssColorString('rgba(23, 143, 156, 0.595)'), //背景颜色
// backgroundColor: Cesium.Color.BLUE, //背景颜色
// backgroundPadding: new Cesium.Cartesian2(7, 5),
style: Cesium.LabelStyle.FILL,
// 名字 类型 描述
// FILL 数 填写标签的文本,但不勾勒出轮廓。
// OUTLINE 数 勾勒出标签文本的轮廓,但不填写。
// FILL_AND_OUTLINE 数 填充并勾勒出标签的文本。
// outlineWidth: 2,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,//水平位置
pixelOffset: new Cesium.Cartesian2(0, -10),
// text: '起 点',
// font: 'normal 8px SimHei',
// fillColor: Cesium.Color.BLUE,
// backgroundColor: Cesium.Color.WHITE, //背景颜色
// //showBackground:true,
// style: Cesium.LabelStyle.FILL, //label样式 FILL、OUTLINE、FILL_AND_OUTLINE
// outlineWidth: 2,
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
// horizontalOrigin: Cesium.HorizontalOrigin.LEFT,//水平位置
// pixelOffset: new Cesium.Cartesian2(0, -10),
}
});
});
}
})
} else {
// deleteRangeArea()
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);//停止监听移动事件
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);//停止监听移动事件
}
},
/*
测面
*/
area(entitiesName) {
entitiesName = entitiesName ? entitiesName : ''
let viewer = this.viewer
if (viewer) {
if (this.handler) {
this.handler.destroy(); //关闭事件句柄
this.handler = undefined;
}
return new Promise((resolve, reject) => {
// deleteRangeArea()
// 取消双击事件-追踪该位置
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);
this.handler = handler
var positions = [];
var tempPoints = [];
var polygon = null;
var cartesian = null;
//鼠标移动事件
handler.setInputAction(function (movement) {
let ray = viewer.camera.getPickRay(movement.endPosition);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
if (!Cesium.defined(cartesian)) //跳出地球时异常
return;
if (positions.length >= 2) {
if (!Cesium.defined(polygon)) {
polygon = new PolygonPrimitive(positions);
} else {
positions.pop();
positions.push(cartesian);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//鼠标左键点击事件
handler.setInputAction(function (movement) {
let ray = viewer.camera.getPickRay(movement.position);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
if (!Cesium.defined(cartesian)) //跳出地球时异常
return;
if (positions.length === 0) {
positions.push(cartesian.clone());
}
positions.push(cartesian);
//在三维场景中添加点
var cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);
var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
var heightString = cartographic.height;
tempPoints.push({ lon: longitudeString, lat: latitudeString, hei: heightString });
viewer.entities.add({
name: entitiesName,
position: positions[positions.length - 1],
point: {
pixelSize: 4,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
}
});
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
//鼠标左键双击事件
handler.setInputAction(function (movement) {
let ray = viewer.camera.getPickRay(movement.position);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
if (!Cesium.defined(cartesian)) //跳出地球时异常
return;
if (positions.length === 0) {
positions.push(cartesian.clone());
}
positions.push(cartesian);
//在三维场景中添加点
var cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);
var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
var heightString = cartographic.height;
tempPoints.push({ lon: longitudeString, lat: latitudeString, hei: heightString });
viewer.entities.add({
name: entitiesName,
position: positions[positions.length - 1],
point: {
pixelSize: 4,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
}
});
handler.destroy();
var textArea = getArea(tempPoints) + "平方千米";
resolve(textArea)
viewer.entities.add({
name: entitiesName,
position: positions[positions.length - 1],
label: {
text: textArea,
font: '14px sans-serif',
fillColor: Cesium.Color.WHITE,
showBackground: true,//是否显示背景颜色
// backgroundColor:Cesium.Color.WHITE, //背景颜色
// style: Cesium.LabelStyle.FILL,
outlineWidth: 3,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,//水平位置
pixelOffset: new Cesium.Cartesian2(0, -10),
}
});
// }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
var radiansPerDegree = Math.PI / 180.0;//角度转化为弧度(rad)
var degreesPerRadian = 180.0 / Math.PI;//弧度转化为角度
//计算多边形面积
function getArea(points) {
var res = 0;
//拆分三角曲面
for (var i = 0; i < points.length - 2; i++) {
var j = (i + 1) % points.length;
var k = (i + 2) % points.length;
var totalAngle = Angle(points[i], points[j], points[k]);
var dis_temp1 = distance(positions[i], positions[j]);
var dis_temp2 = distance(positions[j], positions[k]);
res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle));
}
return (res / 1000000.0).toFixed(4);
}
/*角度*/
function Angle(p1, p2, p3) {
var bearing21 = Bearing(p2, p1);
var bearing23 = Bearing(p2, p3);
var angle = bearing21 - bearing23;
if (angle < 0) {
angle += 360;
}
return angle;
}
/*方向*/
function Bearing(from, to) {
var lat1 = from.lat * radiansPerDegree;
var lon1 = from.lon * radiansPerDegree;
var lat2 = to.lat * radiansPerDegree;
var lon2 = to.lon * radiansPerDegree;
var angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
if (angle < 0) {
angle += Math.PI * 2.0;
}
angle = angle * degreesPerRadian;//角度
return angle;
}
var PolygonPrimitive = (function () {
function _(positions) {
this.options = {
name: '_range',
polygon: {
hierarchy: [],
// perPositionHeight : true,
material: Cesium.Color.GREEN.withAlpha(0.5),
// heightReference:20000
}
};
this.hierarchy = { positions };
this._init();
}
_.prototype._init = function () {
var _self = this;
var _update = function () {
return _self.hierarchy;
};
//实时更新polygon.hierarchy
this.options.polygon.hierarchy = new Cesium.CallbackProperty(_update, false);
viewer.entities.add(this.options);
};
return _;
})();
/*两点间距离*/
function distance(point1, point2) {
var point1cartographic = Cesium.Cartographic.fromCartesian(point1);
var point2cartographic = Cesium.Cartographic.fromCartesian(point2);
/**根据经纬度计算出距离**/
var geodesic = new Cesium.EllipsoidGeodesic();
geodesic.setEndPoints(point1cartographic, point2cartographic);
var s = geodesic.surfaceDistance;
//返回两点之间的距离
s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
return s;
}
})
} else {
// deleteRangeArea()
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);//停止监听移动事件
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);//停止监听移动事件
}
},
// 放大
zoomIn(value = 1000) {
let viewer = this.viewer
let minimumZoomDistance = viewer.scene.screenSpaceCameraController.minimumZoomDistance;
// 当前zoom
let zoom = viewer.camera.positionCartographic.height
// 不等于无穷,即设置了最大高度
if (minimumZoomDistance !== 1) {
// 当前高度-要放大的高度
if (zoom - minimumZoomDistance < 0) {
console.log('不能再缩放了,超出用户限制')
return
}
viewer.camera.zoomIn(value)
} else {//未设置限制
if (zoom - value < 0) {
console.log('不能再缩放了,超出地图限制')
return
}
viewer.camera.zoomIn(value)
}
},
// 缩小,(其实就是放大高度)
zoomOut(value = 100) {
let viewer = this.viewer
// 用户设置的最大
let maximumZoomDistance = viewer.scene.screenSpaceCameraController.maximumZoomDistance;
// 当前zoom
let zoom = viewer.camera.positionCartographic.height
// // 不等于无穷,即设置了最大高度
if (maximumZoomDistance !== Infinity) {
// 当前高度+要放大的高度>最大高度
if (zoom + value > maximumZoomDistance) {
// 如果当前高度等于最大高度,则不能再缩放
if (Math.round(zoom) === Math.round(maximumZoomDistance)) {
console.log('不能再缩放了')
return
} else {//直接缩放到用户限制的高度
// 获取相机对象
let camera = viewer.camera;
// 获取相机位置的Cartographic坐标
let cameraPosition = camera.positionCartographic;
// 将Cartographic高度设置为新值
cameraPosition.height = maximumZoomDistance;
// 将相机位置设置为更新后的Cartographic坐标
camera.setView({
destination: Cesium.Cartesian3.fromRadians(cameraPosition.longitude, cameraPosition.latitude, cameraPosition.height)
});
console.log('小于value,直接到限制')
return
}
}
// 可继续缩小
viewer.camera.zoomOut(value)
}
// 可继续缩小
viewer.camera.zoomOut(value)
},
}
export default cesiumPublic
使用
import cesiumPublic from '@/utils/Cesium/usePublic.js'
//地图初始化时,初始化函数
cesiumPublic.init(viewe)
//使用测距
cesiumPublic.range('测距')
//监听测距完成可使用 await
let data = await cesiumPublic.range('测距')