代码效果
安装Cesium
1、需要进行安装 npm install vue-cesium --savemain.js全局注册
import VueCesium from 'vue-cesium'; Vue.use(VueCesium);组件代码如下
<template> <div class="viewer"> <vc-viewer @ready="ready"> <!-- 抛物线 --> <template v-for="(item, index) in positionsParabola"> <vc-trail-polyline :key="'parabola2' + index" :positions="item" color="yellow" imageUrl="https://zouyaoji.top/vue-cesium/statics/SampleData/images/colors.png" :width="2" ref="parabola" :clampToGround="true" :loop="true" ></vc-trail-polyline> </template> <template v-for="(item, index) in points"> <vc-entity :position="item" :key="index"> <vc-graphics-point :key="index" :color="item.color" :pixelSize="item.size" :disableDepthTestDistance="Number.POSITIVE_INFINITY" ></vc-graphics-point> </vc-entity> </template> <!-- 这里是地球样式区域,官方demo是高清版本,这个token后续需要注意一下 --> <vc-layer-imagery> <vc-provider-imagery-tianditu mapStyle="img_c" token="436ce7e50d27eede2f2929307e6b33c0" ></vc-provider-imagery-tianditu> </vc-layer-imagery> </vc-viewer> </div> </template> <script> export default { props: { // 节点数据 nodeInfo: { required: true, type: Array } }, data() { return { // node节点数据 points: [], // 原始数据 points2: [], positionsParabola: [], }; }, created() { // --------------这部分测试数据后续去掉----------- var tmpPoints = [ [ { "id": 6, "lng": 101.028495718, "lat": 29.200814617, color: "YELLOW", size: 15, }, { "id": 7, "lng": 117.795000473, "lat": 30.638540762, color: "RED", size: 15, }, { "id": 8, "lng": 119.267729446, "lat": 30.698151246, color: "BLUE", size: 15, }, { "id": 9, lng: 121.126643144, lat: 30.058588576, color: "GREEN", size: 15, }, { "id": 10, lng: 120.885884938, lat: 31.395401912, color: "BLUE", size: 15, }, { "id": 11, lng: 128.885884938, lat: 31.495401912, color: "BLUE", size: 15, } ], [ { id: 1, lng: 115.028495718, lat: 30.200814617, color: "YELLOW", size: 15, }, { id: 2, lng: 110.795000473, lat: 32.638540762, color: "RED", size: 15, }, { id: 3, lng: 111.267729446, lat: 30.698151246, color: "BLUE", size: 15, }, { id: 4, lng: 112.126643144, lat: 32.058588576, color: "GREEN", size: 15, }, { id: 5, lng: 114.885884938, lat: 30.395401912, color: "BLUE", size: 15, } ] ]; // --------------这部分测试数据后续去掉----------- // 开始遍历points列表 var _this = this; // 清空线条数据 _this.positionsParabola = []; // 清空节点数据 _this.points = []; // 判断数据类型,如果数据类型符合,则开始数据赋值工作 if (_this.nodeInfo instanceof Array) { if (_this.nodeInfo.length > 0) { _this.runNodeInfo(_this.nodeInfo); } } // 测试用的区域,正式部署去掉就行 else { _this.runNodeInfo(tmpPoints); } }, mounted() { const promises = []; console.log(this.$refs.parabola); // 数据封装 this.$refs.parabola.forEach((v) => { if (v.hasOwnProperty('createPromise')){ promises.push(v.createPromise); } }); }, methods: { // 数据处理 runNodeInfo(originArray) { var _this = this; _this.points2 = originArray; var element = _this.points2; // 开始解析数据 element.forEach(item => { // 生成随机颜色值 var nodeColor = _this.randomRGB(); item.forEach((childItem, childIndex) => { // 颜色赋值 childItem['color'] = nodeColor; // size字段设置 childItem['size'] = 15; // 添加节点数据 _this.points.push(childItem); var startP = { lng: childItem.lng, lat: childItem.lat }; var endP = ((childIndex + 1) == item.length) ? item[childIndex]: item[childIndex + 1]; const positions = _this.parabolaEquation({ startPoint: startP, endPoint: endP, height: 50, num: 50, }); _this.positionsParabola.push(positions); }); }); }, // 生成随机颜色代码 randomRGB() { var r = Math.floor(Math.random()*256); var g = Math.floor(Math.random()*256); var b = Math.floor(Math.random()*256); var nodeColor = '#'+r.toString(16)+g.toString(16)+b.toString(16); return nodeColor; }, ready(cesiumInstance) { this.cesiumInstance = cesiumInstance; const { Cesium, viewer } = this.cesiumInstance; viewer.scene.globe.depthTestAgainstTerrain = true; }, // 这里其实就是在绘制线条 parabolaEquation(options) { // 方程 y=-(4h/L^2)*x^2+h h:顶点高度 L:横纵间距较大者 const h = options.height && (options.height < 5000) ? options.height : 5000; const L = Math.abs(options.startPoint.lng - options.endPoint.lng) > Math.abs(options.startPoint.lat - options.endPoint.lat) ? Math.abs(options.startPoint.lng - options.endPoint.lng) : Math.abs(options.startPoint.lat - options.endPoint.lat); // 这里是num的数值被限制在最低50 const num = options.num && options.num > 50 ? options.num : 50; const result = []; let dlt = L / num; if ( Math.abs(options.startPoint.lng - options.endPoint.lng) > Math.abs(options.startPoint.lat - options.endPoint.lat)) { //以 lng 为基准 const delLat = (options.endPoint.lat - options.startPoint.lat) / num; if (options.startPoint.lng - options.endPoint.lng > 0) { dlt = -dlt; } // 遍历 for (let i = 0; i < num; i++) { // math.pow 是在做指数幂运算,说认真的,这个地方完全没看懂函数起的作用 const tempH = h - (Math.pow(-0.5 * L + Math.abs(dlt) * i, 2) * 4 * h) / Math.pow(L, 2); // 重新定义lng 和 lat参数_this const lng = options.startPoint.lng + dlt * i; const lat = options.startPoint.lat + delLat * i; result.push({ lng, lat, height: tempH }); } } else { //以 lat 为基准 let dellng = (options.endPoint.lng - options.startPoint.lng) / num; if (options.startPoint.lat - options.endPoint.lat > 0) { dlt = -dlt; } for (let i = 0; i < num; i++) { const tempH = h - (Math.pow(-0.5 * L + Math.abs(dlt) * i, 2) * 4 * h) / Math.pow(L, 2); // 重新定义lng 和 lat参数_this const lng = options.startPoint.lng + dellng * i; const lat = options.startPoint.lat + dlt * i; result.push({ lng, lat, height: tempH }); } } // 落地 result.push({ lng: options.endPoint.lng, lat: options.endPoint.lat, height: options.endPoint.height || 0, }); return result; }, }, }; </script> <style lang="scss" scoped> .viewer { margin: 0; padding: 0; width: 100%; height: 100%; } </style>