div页面
<div id="cesiumDemo"></div>
<button @click="draw('Polyline')">标点测距</button>
<button @click="draw('Polygon')">标点测面</button>
<button @click="clearAllDrawn()">清空数据</button>
script页面
import { getLength,getMidpoint,addLabel,Bearing,drawPolyline,drawPolygon,drawPoint,addArea,drawPointLabel
} from '../../assets/js/MeasureManager.js'
export default {
data() {
return {
viewer: undefined,
tempEntities: [],
pointNum: 0,
floatingPoint: undefined,
activeShape: undefined,
}
},
mounted() {
this.getCesiumDem()
},
methods: {
pointAngle (point1, point2, point3) {
let bearing21 = Bearing(point2, point1)
let bearing23 = Bearing(point2, point3)
let angle = bearing21 - bearing23
if (angle < 0) {
angle += Math.PI * 2.0
}
return angle
},
getArea(positions) {
let res = 0
for (let i = 0; i < positions.length - 2; i++) {
let j = (i + 1) % positions.length
let k = (i + 2) % positions.length
let totalAngle = this.pointAngle(positions[i], positions[j], positions[k])
let tempLength1 = getLength(positions[j], positions[0])
let tempLength2 = getLength(positions[k], positions[0])
res += tempLength1 * tempLength2 * Math.sin(totalAngle) / 2
}
res = res.toFixed(2)
res = parseFloat(res)
return Math.abs(res)
},
clearAllDrawn () {
this.tempEntities = []
this.pointNum = 0
viewer.entities.removeAll()
},
draw (type) {
let that = this
let tempEntities = this.tempEntities
let floatingPoint = this.floatingPoint
let activeShape = this.activeShape
let position = []
let tempPoints = []
let activeShapePoints = []
viewer.scene.globe.depthTestAgainstTerrain = true
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
switch (type) {
case 'Polyline':
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
handler.setInputAction(function (movement) {
if (Cesium.defined(floatingPoint)) {
let newPosition = viewer.scene.pickPosition(movement.endPosition)
if (Cesium.defined(newPosition)) {
floatingPoint.position.setValue(newPosition)
activeShapePoints.pop()
activeShapePoints.push(newPosition)
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
handler.setInputAction(function (click) {
let earthPosition = viewer.scene.pickPosition(click.position)
if (Cesium.defined(earthPosition)) {
floatingPoint = drawPoint(viewer,earthPosition)
}
let ray = viewer.camera.getPickRay(click.position)
position = viewer.scene.globe.pick(ray, viewer.scene)
tempPoints.push(position)
that.pointNum += 1
let tempLength = tempPoints.length
let point = drawPointLabel(viewer,tempPoints[tempPoints.length - 1], JSON.stringify(that.pointNum))
tempEntities.push(point)
if (tempLength > 1) {
let pointLength = getLength(tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1])
let midPosition = getMidpoint(tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1])
let pointline = drawPolyline(viewer,[tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1]])
let pointLabel = addLabel(viewer,midPosition, pointLength)
tempEntities.push(pointline)
tempEntities.push(pointLabel)
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
handler.setInputAction(function (click) {
activeShapePoints.pop()
viewer.entities.remove(activeShapePoints)
viewer.entities.remove(floatingPoint)
tempPoints = []
handler.destroy()
handler = null
floatingPoint = undefined
activeShape = undefined
activeShapePoints = []
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
break
case 'Polygon':
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
handler.setInputAction(function (movement) {
if (Cesium.defined(floatingPoint)) {
let newPosition = viewer.scene.pickPosition(movement.endPosition)
if (Cesium.defined(newPosition)) {
floatingPoint.position.setValue(newPosition)
activeShapePoints.pop()
activeShapePoints.push(newPosition)
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
handler.setInputAction(function (click) {
let earthPosition = viewer.scene.pickPosition(click.position)
if (Cesium.defined(earthPosition)) {
if (activeShapePoints.length === 0) {
floatingPoint = drawPoint(viewer,earthPosition)
activeShapePoints.push(earthPosition)
const dynamicPositions = new Cesium.CallbackProperty(function () {
return new Cesium.PolygonHierarchy(activeShapePoints)
}, false)
activeShape = drawPolygon(viewer,dynamicPositions)
}
activeShapePoints.push(earthPosition)
}
let ray = viewer.camera.getPickRay(click.position)
position = viewer.scene.globe.pick(ray, viewer.scene)
tempPoints.push(position)
let tempLength = tempPoints.length
that.pointNum += 1
let point = drawPointLabel(viewer,tempPoints[tempPoints.length - 1], JSON.stringify(that.pointNum))
tempEntities.push(point)
if (tempLength > 1) {
let pointline = drawPolyline(viewer,[tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1]])
tempEntities.push(pointline)
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
handler.setInputAction(function (click) {
let cartesian = viewer.camera.pickEllipsoid(click.position, viewer.scene.globe.ellipsoid)
if (cartesian) {
let tempLength = tempPoints.length
if (tempLength < 3) {
alert('闭合操作需要至少3个点嗷')
} else {
let pointline = drawPolyline(viewer,[tempPoints[0], tempPoints[tempPoints.length - 1]])
tempEntities.push(pointline)
drawPolygon(viewer,tempPoints)
let pointArea = that.getArea(tempPoints)
addArea(viewer,JSON.stringify(pointArea), tempPoints)
tempEntities.push(tempPoints)
handler.destroy()
handler = null
}
}
activeShapePoints.pop()
viewer.entities.remove(activeShapePoints)
viewer.entities.remove(floatingPoint)
floatingPoint = undefined
activeShapePoints = []
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
break
}
},
getCesiumDem() {
let self = this
Cesium.Ion.defaultAccessToken ='你的token'
viewer = new Cesium.Viewer('cesiumDemo', {
animation: false,
baseLayerPicker: false,
geocoder: false,
timeline: false,
sceneModePicker: true,
navigationHelpButton: false,
infoBox: true,
fullscreenButton: false,
selectionIndicator: false,
scene3DOnly: true,
homeButton: false,
terrainProvider: new Cesium.EllipsoidTerrainProvider({}),
}
}
公用组件的封装
export function getLength(start, end) {
let startCartographic = Cesium.Cartographic.fromCartesian(start)
let endCartographic = Cesium.Cartographic.fromCartesian(end)
let geodesic = new Cesium.EllipsoidGeodesic()
geodesic.setEndPoints(startCartographic, endCartographic)
return (geodesic.surfaceDistance / 1000).toFixed(2)
}
export function getMidpoint(start, end) {
let startPoint = Cesium.Cartographic.fromCartesian(start)
let endPoint = Cesium.Cartographic.fromCartesian(end)
let geodesic = new Cesium.EllipsoidGeodesic()
geodesic.setEndPoints(startPoint, endPoint)
let geoPoint = geodesic.interpolateUsingFraction(0.5)
console.log(Cesium.Ellipsoid.WGS84.cartographicToCartesian(geoPoint))
return Cesium.Ellipsoid.WGS84.cartographicToCartesian(geoPoint)
}
export function addLabel(viewer,midPoint, labelLength) {
return viewer.entities.add({
name: '中点',
position: midPoint,
label: {
text: labelLength + 'km',
font: '20px sans-serif',
fillColor: Cesium.Color.WHITE,
outlineWidth: 2,
backgroundColor: Cesium.Color.BLACK,
showBackground: true,
style: Cesium.LabelStyle.FILL,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY
}
})
}
export function Bearing(from, to) {
let fromCartographic = Cesium.Cartographic.fromCartesian(from)
let toCartographic = Cesium.Cartographic.fromCartesian(to)
let lat1 = fromCartographic.latitude
let lon1 = fromCartographic.longitude
let lat2 = toCartographic.latitude
let lon2 = toCartographic.longitude
let 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
}
return angle
}
export function addArea(viewer,area, positions) {
return viewer.entities.add({
name: '多边形面积',
position: positions[positions.length - 1],
label: {
text: area + '平方公里',
font: '20px sans-serif',
fillColor: Cesium.Color.WHITE,
outlineWidth: 2,
backgroundColor: Cesium.Color.BLACK,
showBackground: true,
style: Cesium.LabelStyle.FILL,
pixelOffset: new Cesium.Cartesian2(60, -60),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY
}
})
}
export function drawPointLabel(viewer,position, pointNum) {
return viewer.entities.add({
name: '点几何对象',
position: position,
point: {
color: Cesium.Color.WHEAT,
pixelSize: 5,
outlineWidth: 3,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
},
label: {
text: pointNum,
font: '30px sans-serif',
fillColor: Cesium.Color.WHITE,
outlineWidth: 2,
backgroundColor: Cesium.Color.BLACK,
showBackground: true,
style: Cesium.LabelStyle.FILL,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER
}
})
}
export function drawPoint(viewer,position) {
return viewer.entities.add({
position: position,
point: {
color: Cesium.Color.WHEAT,
pixelSize: 5,
outlineWidth: 3,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
}
})
}
export function drawPolyline(viewer,positions) {
if (positions.length < 1) return
return viewer.entities.add({
name: '线几何对象',
polyline: {
positions: positions,
width: 5.0,
material: new Cesium.PolylineGlowMaterialProperty({
color: Cesium.Color.WHEAT
}),
depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
color: Cesium.Color.WHEAT
}),
clampToGround: true
}
})
}
export function drawPolygon(viewer,positions) {
if (positions.length < 2) return
return viewer.entities.add({
name: '面几何对象',
polygon: {
hierarchy: positions,
material: new Cesium.ColorMaterialProperty(
Cesium.Color.WHEAT.withAlpha(0.4)
)
}
})
}