Cesium图形绘制

0.引言

现有的gis开发方向较流行的是webgis开发,其中Cesium是一款开源的WebGIS库,主要用于实时地球和空间数据的可视化和分析。它提供了丰富的地图显示和数据可视化功能,并能实现三维可视化开发。本文介绍Cesium中的坐标系统及相互转换关系,讲解如何在构造的三维场景中交互绘制点、线、面、体等多种空间对象并对这些空间对象进行管理。

1.坐标系统

Cesium中经常会涉及各类数据的加载、浏览,以及不同数据之间的坐标转换,所以我们不得不弄清楚Cesium中常用的坐标系统,以及不同坐标系统之间的转换关系和转换方法等。这里主要介绍Cesium中常用的WGS-84坐标系(包括弧度和度的形式)、世界坐标系(笛卡儿空间直角坐标系)及平面坐标系,并介绍这些坐标系统之间的转换关系和转换方法。
(1)坐标系统相互转换代码
  在这里插入图片描述

4_1_坐标转换.html
<!DOCTYPE html>
<html lang="en">  
  
<head>  
    <meta charset="UTF-8">  
    <meta http-equiv="X-UA-Compatible" content="IE=edge">  
    <meta name="viewport" content="width=device-width, initial-scale=1.0">  
    <title>场景绘制篇_坐标转换</title>  
    <script src="./Build/Cesium/Cesium.js"></script>  
    <link rel="stylesheet" href="./Build/Cesium//Widgets/widgets.css">  
    <style>  
        html,  
        body,  
        #cesiumContainer {  
            width: 100%;  
            height: 100%;  
            margin: 0;  
            padding: 0;  
            overflow: hidden;  
        }  
    </style>  
</head>  
  
<body>  
    <div id="cesiumContainer">  
    </div>  
  
    <script>  
        Cesium.Ion.defaultAccessToken = '你的token';  
        var viewer = new Cesium.Viewer("cesiumContainer", {
   
     
            animation: false, //是否显示动画工具  
            timeline: false,  //是否显示时间轴工具  
            fullscreenButton: false,  //是否显示全屏按钮工具  
        });  
        viewer.scene.globe.depthTestAgainstTerrain = true  
  
        var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);  
        handler.setInputAction(function (movement) {
   
     
            //屏幕坐标  
            console.log('屏幕坐标:', movement.position);  
  
            //屏幕坐标 转 世界坐标(场景坐标,包括地形、倾斜摄影模型等的坐标)  
            var cartesian3= viewer.scene.pickPosition(movement.position);    //注意此处的屏幕坐标一定要在球上,否则结果为undefined  
            console.log('屏幕坐标转世界坐标(场景):', cartesian3);  
  
            //屏幕坐标 转 世界坐标(地表坐标,包括地形但不包括模型、倾斜摄影等)  
            var ray = viewer.camera.getPickRay(movement.position);  
            var cartesian3 = viewer.scene.globe.pick(ray, viewer.scene);  
            console.log('屏幕坐标转世界坐标(地表):', cartesian3);  
  
            //屏幕坐标 转 世界坐标(椭球面坐标,不包括地形、模型、倾斜摄影等)  
            var cartesian3= viewer.scene.camera.pickEllipsoid(movement.position)  
            console.log('屏幕坐标转世界坐标(椭球面):', cartesian3);  
  
            //世界坐标 转 屏幕坐标  
            var cartesian2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, cartesian3)  
            console.log('世界坐标转屏幕坐标:', cartesian2);  
  
            //世界坐标 转 WGS84坐标,结果为弧度形式  
            var cartographic = Cesium.Cartographic.fromCartesian(cartesian3);  
            console.log('世界坐标转WGS84弧度坐标:', cartographic);  
  
            //WGS84弧度坐标 转 经纬度坐标  
            longitude = Cesium.Math.toDegrees(cartographic.longitude);  
            latitude = Cesium.Math.toDegrees(cartographic.latitude);  
            height = cartographic.height;  
            console.log('WGS84弧度坐标转WGS84经纬度坐标:' + longitude + ',' + latitude + ',' + height);  
  
            //WGS84经纬度坐标 转 弧度坐标  
            var radians = Cesium.Cartographic.fromDegrees(longitude, latitude, height);  
            console.log('WGS84经纬度转WGS84弧度坐标', radians);  
  
            //WGS84经纬度坐标 转 世界坐标  
            var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);  
            console.log('WGS84经纬度转世界坐标', position);  
  
            //WGS84弧度坐标 转 世界坐标  
            var position2 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height);  
            console.log('WGS84弧度转世界坐标', position2);  
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);  
  
    </script>  
</body>  
  
</html>

(2)结果输出
运行代码后出现网页地球,按F12,调出控制台,点击球体一个位置,下图右侧控制台显示屏幕点坐标及其他坐标转换结果。
  在这里插入图片描述

2.几何图形绘制

几何图形绘制一直以来都是GIS必备的基础功能之一,例如,点、线、面的绘制在各种GIS中屡见不鲜,而Cesium不仅支持点、线、面的绘制,还支持柱体、椭球体、盒子及三维模型等几何图形的绘制。
Cesium在几何图形绘制方面提供了两种不同类型的API:一种是较为高级的,不需要使用者对计算机图形学有很深的理解,可以直接拿来使用的API,即Entity API;另一种是面向图形开发人员的,更为复杂的API,即Primitive API。对于新手来说,本书推荐使用Entity API,因为Entity API本质上是对Primitive API的二次封装,目的是让使用者不必对计算机图形学有多么高深的理解,就能轻松绘制出各式各样的几何图形。

2.1Entity绘制实体

Entity通过Entity类实现实体绘制,支持点、线、面、椭球体、广告牌、盒子、标签、模型、墙等多种实体的绘制。用户可以手动创建实体并将它们添加到场景中,或者由数据源(如CzmlDataSource和GeoJsonDataSource)进行添加。此处以手动创建并添加实体为例来介绍各种类型的实体绘制方式。
(1)关键代码
  在这里插入图片描述

4_2.1_Entity方式直接绘制.html
<!DOCTYPE html>
<html lang="en">  
  
<head>  
  <meta charset="UTF-8">  
  <meta http-equiv="X-UA-Compatible" content="IE=edge">  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">  
  <title>绘制实体_Entity方式</title>  
  <script src="./Build/Cesium/Cesium.js"></script>  
  <link rel="stylesheet" href="./Build/Cesium//Widgets/widgets.css">  
  <!-- <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script> -->  
  <style>  
    html,  
    body,  
    #cesiumContainer {  
      width: 100%;  
      height: 100%;  
      margin: 0;  
      padding: 0;  
      overflow: hidden;  
    }  
  
    .toolbar {
   
     
      position: absolute;  
      top: 10px;  
      left: 20px;  
      background-color: rgb(0, 0, 0, 0);  
    }  
  </style>  
</head>  
  
<body>  
  <div id="cesiumContainer">  
  </div>  
  <div id="menu" class="toolbar">  
    <select id="dropdown" onchange="addEntity()">  
      <option value="null">null</option>  
      <option value="addPoint">添加点</option>  
      <option value="addLines">添加线</option>  
      <option value="addPolygon">添加面</option>  
      <option value="addRectangle">添加矩形</option>  
      <option value="addEllipse">添加椭圆</option>  
      <option value="addCylinder">添加圆柱体</option>  
      <option value="addCorridor">添加走廊</option>  
      <option value="addWall">添加墙</option>  
      <option value="addBox">添加方盒</option>  
      <option value="addEllipsoid">添加球体</option>  
      <option value="addModel">添加模型</option>  
      <option value="addBillboard">添加广告牌</option>  
    </select>  
  
    <select id="dropdown2" onchange="removeEntity()">  
      <option value="null">null</option>  
      <option value="removePoint">删除点</option>  
      <option value="removeLines">删除线</option>  
      <option value="removePolygon">删除面</option>  
      <option value="removeRectangle">删除矩形</option>  
      <option value="removeEllipse">删除椭圆</option>  
      <option value="removeCylinder">删除圆柱体</option>  
      <option value="removeCorridor">删除走廊</option>  
      <option value="removeWall">删除墙</option>  
      <option value="removeBox">删除方盒</option>  
      <option value="removeEllipsoid">删除球体</option>  
      <option value="removeModel">删除模型</option>  
      <option value="removeBillboard">删除广告牌</option>  
    </select>  
  </div>  
  
  <script>  
    Cesium.Ion.defaultAccessToken =  
      '你的token';  
    var viewer = new Cesium.Viewer("cesiumContainer", {
   
     
      animation: false, //是否显示动画工具  
      timeline: false, //是否显示时间轴工具  
      fullscreenButton: false, //是否显示全屏按钮工具  
    });  
  
    viewer.camera.flyTo({
   
     
      destination: Cesium.Cartesian3.fromDegrees(118, 32, 6000000),  
      orientation: {
   
     
        heading: 0.010152402293521767,  
        pitch: -1.5705337480193866,  
        roll: 0.00003681052934645379  
      },  
    })  
  
    // 点  
    var addPoint = {
   
     
      id: 'point',  
      name: '点',  
      show: true, //显示.  
      position: Cesium.Cartesian3.fromDegrees(118, 32, 0.0),  
      point: {
   
     
        color: Cesium.Color.BLUE, //颜色  
        pixelSize: 5, //点大小  
      }  
    }  
  
    // 线  
    var addLine = {
   
     
      id: 'line',  
      name: '线',  
      show: true, //显示  
      polyline: {
   
     
        positions: Cesium.Cartesian3.fromDegreesArray([118, 30, 119, 32, 116, 35]),  
        width: 1, //线条粗细  
        material: Cesium.Color.RED, //线条材质  
        //clampToGround: true  
      }  
    }  
  
    //面  
    var addPolygon = {
   
     
      id: 'polygon',  
      name: '面',  
      show: true,  
      polygon: {
   
     
        hierarchy: Cesium.Cartesian3.fromDegreesArray([118, 30, 119, 32, 116, 32, 116, 30]),  
        //outline: false,  
        material: Cesium.Color.RED.withAlpha(0.4),  
      }  
    }  
  
    //矩形  
    var addRectangle = {
   
     
      id: 'rectangle',  
      name: '矩形',  
      show: true,  
      rectangle: {
   
     
        coordinates: Cesium.Rectangle.fromDegrees(80.0, 30.0, 100.0, 35.0),  
        material: Cesium.Color.BLUE.withAlpha(0.5),  
        /* height:0,  
           outline: true,  
        outlineWidth:10,  
  
           outlineColor: Cesium.Color.BLUE */  
      }  
    }  
  
    //椭圆  
    var addEllipse = {
   
     
      id: 'ellipse',  
      name: '椭圆',  
      show: true,  
      position: Cesium.Cartesian3.fromDegrees(103.0, 40.0),  
      ellipse: {
   
     
        semiMinorAxis: 250000.0, //短半轴  
        semiMajorAxis: 400000.0, //长半轴  
        material: Cesium.Color.RED.withAlpha(0.5),  
        /* height:0,  
           outline: true,  
           outlineColor: Cesium.Color.RED */  
      }  
    }  
  
    //圆柱体  
    var addCylinder = {
   
     
      id: 'cylinder',  
      name: '圆柱体',  
      show: true,  
      //位置  
      position: Cesium.Cartesian3.fromDegrees(100.0, 40.0, 200000.0),  
      cylinder: {
   
     
        length: 400000.0, //圆柱长度  
        topRadius: 200000.0, //顶面半径  
        bottomRadius: 200000.0, //底面半径  
        material: Cesium.Color.GREEN.withAlpha(0.6),  
        outline: false,  
        outlineColor: Cesium.Color.DARK_GREEN  
      }  
    }  
  
    //走廊  
    var addCorridor = {
   
     
      id: 'corridor',  
      name: '走廊',  
      show: true,  
      corridor: {
   
     
        positions: Cesium.Cartesian3.fromDegreesArray([  
          100.0, 40.0,  
          105.0, 40.0,  
          105.0, 35.0  
        ]),  
        width: 200000.0,  
        material: Cesium.Color.YELLOW.withAlpha(0.5),  
        /* height:0,  
           outline: true,        //外轮廓线  
           outlineColor: Cesium.Color.RED */  
      }  
    }  
  
    //墙  
    var addWall = {
   
     
      id: 'wall',  
      name: '墙',  
      show: true,  
      wall: {
   
     
        positions: Cesium.Cartesian3.fromDegreesArrayHeights([  
          107.0, 43.0, 200000.0,  
          97.0, 43.0, 100000.0,  
          97.0, 40.0, 100000.0,  
          107.0, 40.0, 100000.0,  
          107.0, 43.0, 100000.0  
        ]),  
        material: Cesium.Color.GREEN  
      }  
    }  
  
    //方盒  
    var addBox = {
   
     
      id: 'box',  
      name: '方盒',  
      show: true,  
      position: Cesium.Cartesian3.fromDegrees(110, 35, 200000.0),  
      box: {
   
     
        dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 400000.0), //指定框的长度,宽度和高度  
        material: Cesium.Color.BLUE  
      }  
    }  
  
    //球体  
    var addEllipsoid = {
   
     
      id: 'ellipsoid',  
      name: '椭球体',  
      show: true,  
      position: Cesium.Cartesian3.fromDegrees(107.0, 40.0, 300000.0),  
      ellipsoid: {
   
     
        radii: new Cesium.Cartesian3(200000.0, 200000.0, 300000.0), //椭球的半径  
        material: Cesium.Color.BLUE.withAlpha(0.5),  
        outline: true,  
        outlineColor: Cesium.Color.WHITE  
      }  
    }  
  
    // 模型  
    var heading = Cesium.Math.toRadians(60); //60度航向  
    var pitch = 0; //俯仰角  
    var roll = 0; //翻滚角  
    var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);  
    var addModel = {
   
     
      id: 'model', //id唯一  
      name: '小车模型', // 名称  
      show: true, //显示  
      position: Cesium.Cartesian3.fromDegrees(118, 30, 5000), // 小车位置  
      orientation: Cesium.Transforms.headingPitchRollQuaternion(Cesium.Cartesian3.fromDegrees(118, 30, 5000),  
      hpr), //飞机航向  
      model: {
   
     
        uri: './3D格式数据/glTF/CesiumMilkTruck.gltf',  
        minimumPixelSize: 300, //模型最小  
        maximumScale: 50000, //模型最大  
        //color: Cesium.Color.ORANGE, // 模型颜色  
        scale: 30000, //当前比例  
      }  
    }  
  
    //广告牌  
    var addBillboard = {
   
     
      id: 'billboard',  
      name: '广告牌',  
      show: true,  
      position: Cesium.Cartesian3.fromDegrees(108, 30, 50),  
      billboard: {
   
     
        image: './RasterImage/图片/single.jpg',  
        scale: 0.1, //比例  
      }  
    }  
    var dropdown = document.getElementById('dropdown');  
    var dropdown2 = document.getElementById('dropdown2');  
  
    function addEntity() {
   
     
      switch (dropdown.value) {
   
     
        case 'addPoint':  
          viewer.entities.add(addPoint);  
          break;  
        case 'addLines':  
          viewer.entities.add(addLine);  
          break;  
        case 'addPolygon':  
          viewer.entities.add(addPolygon);  
          break;  
        case 'addRectangle':  
          viewer.entities.add(addRectangle);  
          break;  
        case 'addEllipse':  
          viewer.entities.add(addEllipse);  
          break;  
        case 'addCylinder':  
          viewer.entities.add(addCylinder);  
          break;  
        case 'addCorridor':  
          viewer.entities.add(addCorridor);  
          break;  
        case 'addWall':  
          viewer.entities.add(addWall);  
          break;  
        case 'addBox':  
          viewer.entities.add(addBox);  
          break;  
        case 'addEllipsoid':  
          viewer.entities.add(addEllipsoid);  
          break;  
        case 'addModel':  
          viewer.entities.add(addModel);  
          break;  
        case 'addBillboard':  
          viewer.entities.add(addBillboard);  
          break;  
        default:  
          break;  
      }  
    }  
  
    function removeEntity() {
   
     
      switch (dropdown2.value) {
   
     
        case 'removePoint':  
          viewer.entities.removeById("point");  
          break;  
        case 'removeLines':  
          viewer.entities.removeById("line");  
          break;  
        case 'removePolygon':  
          viewer.entities.removeById("polygon");  
          break;  
        case 'removeRectangle':  
          viewer.entities.removeById("rectangle");  
          break;  
        case 'removeEllipse'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值