cesium实现绘制线、面贴地效果

3 篇文章 0 订阅
1 篇文章 0 订阅

        此篇在vue里进行cesium整合开发,需要预备vue的开发基础。代码上本人也阅读了官网的例子,借鉴一部分,https://sandcastle.cesium.com/?src=Drawing%20on%20Terrain.html

主要思路如下:

1)鼠标左键单击事件发生,用两个数组来存点坐标
2)鼠标移动事件,利用两个数组长度比较,左键单击事件发生时,两个长度一样,moveposition总添加第一个移动的点坐标;
3)当鼠标移动事件发生时,moveposition长度总比positions多1,moveposition[moveposition.length-1]更新为最后一个动点
4)鼠标左键双击发生时,结束鼠标交互事件

下图为某地的地形,画上贴地线的效果

<template>
  <div id="map" class="map">
      <el-button
         type="warning"
         size="mini"
         style="position:absolute;z-index:10;" @click="drawGeometry('polygon')">绘制面    
      </el-button>
      <el-button
          type="warning"
          size="mini"
          style="position:absolute;z-index:10;margin-left:120px;"                     
          @click="drawGeometry('polyline')" >绘制线
       </el-button>
       <!--隐藏掉CESIUM底部的ICON-->
       <div id="creditContainer" class="creditContainer" 
            style="position:absolute;display:none;">
       </div>
  </div>
</template>

<script>
/*openlayer*/
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import {defaults as defaultControls, ScaleLine} from 'ol/control';
import TileLayer from 'ol/layer/Tile';
import TileWMS from 'ol/source/TileWMS';
import { METHODS } from 'http';
    export default {
        data() {
            return {
                viewer:null,
                handler:null,
                positions:[], //leftclick记录的点
                moveposition:[],// mouse move记录的点,总是比leftclick多一个点
                GeometryShape:null,
            }
        },
        methods:{
            drawGeometry(drawMode){
                let self=this;
                /*
                * 鼠标左键单击事件发生,用两个数组来存点坐标
                * 鼠标移动事件,利用两个数组长度比较,左键单击事件发生时,两个长度一样,moveposition总添加第一个移动的点坐标;
                * 当鼠标移动事件发生时,moveposition长度总比positions多1,moveposition[moveposition.length-1]更新为最后一个动点
                * 鼠标左键双击发生时,结束鼠标交互事件
                */
                self.handler= new Cesium.ScreenSpaceEventHandler(self.viewer.scene.canvas);
                var activePosition;
                self.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
                self.handler.setInputAction(function(e){
                    self.moveposition.pop();
                    self.drawshape(self.moveposition,{
                        drawMode:drawMode,
                        color:Cesium.Color.RED,
                        width:3,
                    });
                    self.viewer.entities.remove(self.GeometryShape);
                    self.GeometryShape = undefined;
                    self.moveposition=[];
                    self.positions=[]
                    self.handler.destroy();
                },Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
                self.handler.setInputAction(function(e){
                    //此获取包含地形坐标的高度
                    var positions= self.viewer.scene.pickPosition(e.position);
                    // let ray = self.viewer.camera.getPickRay(e.position);
                    // let leftclickcartesian = self.viewer.scene.globe.pick(ray, self.viewer.scene);
                    //此获取的是无高度的空间直角坐标系
                    // let positions= self.viewer.camera.pickEllipsoid(e.position, self.viewer.scene.globe.ellipsoid);
                //动态加面改进
                if(self.positions.length==0){
                    activePosition= new Cesium.CallbackProperty(function () {
                        if(drawMode=='polygon'){
                            return new Cesium.PolygonHierarchy(self.moveposition)
                        }   
                            return  self.moveposition;
                    },false)
                    self.GeometryShape=
                    self.drawshape(activePosition,{
                        drawMode:drawMode,
                        color:Cesium.Color.RED,
                        width:3,
                    });
                }
                self.positions.push(positions);
                self.moveposition.push(positions);
                    //动态添加点
                    self.viewer.entities.add({
                        position: positions,
                            point: {
                                pixelSize: 5,
                                color: Cesium.Color.BLUE,
                                outlineColor: Cesium.Color.WHITE,
                                outlineWidth: 1,
                            },
                    });
              }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
              
              self.handler.setInputAction(function(e){
                    // let ray = self.viewer.camera.getPickRay(e.endPosition);
                    // let mousemovecartesian = self.viewer.scene.globe.pick(ray, self.viewer.scene);
                    var mousemovecartesian= self.viewer.scene.pickPosition(e.endPosition);
                    // let mousemovecartesian= self.viewer.camera.pickEllipsoid(e.endPosition, self.viewer.scene.globe.ellipsoid);
                    //两个if条件控制,保证当moveposition的长度与positions的长度一致时,moveposition push 鼠标移动的点
                    if(self.moveposition.length===self.positions.length+1){
                        //当moveposition的长度比positions大1时,一直更新最新的动点
                        self.moveposition[self.moveposition.length-1]=mousemovecartesian;
                        // console.log("this.moveposition",self.moveposition);
                    }
                    else if(self.moveposition.length===self.positions.length){
                        //长度一样添加鼠标动点坐标
                        self.moveposition.push(mousemovecartesian);
                        // console.log("this.moveposition",self.moveposition.length);
                        // console.log("this.positions",self.positions.length);
                    }
                    
              },Cesium.ScreenSpaceEventType.MOUSE_MOVE)
                // this.measure.measureAreaSpace(this.viewer,this.handler);
            },
        //绘制图形的函数
        drawshape(positions, config) {
            var config = config ? config : {};             
            var shape
            if(config.drawMode=="polygon"){                         
                shape = this.viewer.entities.add({                
                    polygon: {                                          
                        hierarchy: positions,//new Cesium.PolygonHierarchy(positions),                     
                        material: config.color ? config.color: new Cesium.ColorMaterialProperty(Cesium.Color.WHITE.withAlpha(0.7)),
                        width:  config.width ? config.width : 2,                               
                    }             
                });
            }else if(config.drawMode=="polyline"){
                 shape = this.viewer.entities.add({           
                    polyline: {
                        clampToGround : true,                     
                        positions: positions,                     
                        material: config.color ? config.color : new Cesium.Color.fromCssColorString("#FFD700").withAlpha(.2),                     
                        width:  config.width ? config.width: 3,                 
                    }             
                });          
            }             
            return shape;  
        },
            init3dmap(){
                 Cesium.Ion.defaultAccessToken ="your access key";
                //初始化3D底图
                 this.viewer = new Cesium.Viewer("map",{
                        geocoder: false,
                        homeButton: false,
                        sceneModePicker: false,
                        baseLayerPicker: false,
                        navigationHelpButton: false,
                        animation: false, //左下角的动画控件的显示
                        shouldAnimate: false, //控制模型动画
                        timeline: false,
                        creditContainer:"creditContainer",
                        creditViewport:"creditContainer",
                        fullscreenButton: false,
                        infoBox:false,
                        terrainProvider : Cesium.createWorldTerrain(),//使用世界地形,默认的地形
                        selectionIndicator : false,
                        // baseLayerPicker:false,
                        // timeline:true,
                        // homeButton:false,
                        // fullscreenButton:false,
                        // infoBox:false,
                        // sceneModePicker:false,
                        // navigationInstructionsInitiallyVisible:false,
                        // navigationHelpButton:false,
                        // shouldAnimate : true
                });
                //开启深度检测,不然画的线面会飘在模型表面
                this.viewer.scene.globe.depthTestAgainstTerrain=true;
                //加载地形
                // viewer.terrainProvider=new Cesium.createWorldTerrain();
                //加载本地发布的地形
                // viewer.terrainProvider = new Cesium. CesiumTerrainProvider({url: "http://localhost/terrain"});
                //不使用地形
                // viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider()

                //相机操作
                this.viewer.scene.camera.setView({
                    destination:new Cesium.Cartesian3.fromDegrees(112.405419,23.073514,20000),
                     orientation: {
                      heading:  0.0, //当前的方向,正北。方位角,北偏东的角度
                      pitch:  Cesium.Math.toRadians(-60),//垂直视线方向和水平面的夹角,Pitch为正 表示方向向量指向水平平面上方,反之表示方向向量指向平面下方,正值从下往上看
                      roll:  0.0 //平面的旋转角度。是方向向量以正东方向为轴的旋转角度,40.0向上翻
                    }
                })
            },

            //init2Dmap openlayer6
            init2dmap(){
                var layers = [
                    new TileLayer({
                        source: new TileWMS({
                        url: 'https://ahocevar.com/geoserver/wms',
                        params: {
                            'LAYERS': 'ne:NE1_HR_LC_SR_W_DR',
                            'TILED': true
                        }
                        })
                    })
                ];

                var map = new Map({
                    controls: defaultControls().extend([
                        new ScaleLine({
                        units: 'degrees'
                        })
                    ]),
                    layers: layers,
                    target: 'map',
                    view: new View({
                        projection: 'EPSG:4326',
                        center: [0, 0],
                        zoom: 2
                    })
                });
            }
        },
        mounted(){
            // this.initmap();
            this.init3dmap();
        }
    }
</script>
<style lang="less">
    .map {
        position: absolute;
        width: 100%;
        // height:600px;
        height:100%;
      }
</style>

 

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
要在Cesium实现抛物线效果,可以使用贝塞尔曲线来模拟抛物线的路径。以下是实现抛物线效果的步骤: 1. 使用entity方式创建一个新的实体对象。 2. 设置实体的position为抛物线的起始点。 3. 使用polyline实例化一个新的PolylineGraphics对象。 4. 将PolylineGraphics对象的positions属性设置为一个包含抛物线路径上的点的数组。 5. 设置PolylineGraphics对象的material为所需的抛物线材质。 6. 将PolylineGraphics对象添加到viewer中。 下面是一个示例代码,展示了如何在Cesium实现抛物线效果: ```javascript // 创建起始点和终点 var start = Cesium.Cartesian3.fromDegrees(113.9236839, 22.528061); var end = Cesium.Cartesian3.fromDegrees(113.925, 22.53); // 计算控制点 var controlPoint = new Cesium.Cartesian3( (start.x + end.x) / 2, (start.y + end.y) / 2, (start.z + end.z) / 2 + 1000 ); // 计算抛物线路径上的点 var numberOfPoints = 100; var positions = []; for (var i = 0; i <= numberOfPoints; i++) { var t = i / numberOfPoints; var x = (1 - t) * (1 - t) * start.x + 2 * (1 - t) * t * controlPoint.x + t * t * end.x; var y = (1 - t) * (1 - t) * start.y + 2 * (1 - t) * t * controlPoint.y + t * t * end.y; var z = (1 - t) * (1 - t) * start.z + 2 * (1 - t) * t * controlPoint.z + t * t * end.z; positions.push(new Cesium.Cartesian3(x, y, z)); } // 创建实体对象 viewer.entities.add({ polyline: { positions: positions, width: 10, material: new Cesium.PolylineGlowMaterialProperty({ glowPower: 0.5, color: Cesium.Color.YELLOW }) } }); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兰小莫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值