Cesium学习笔记9——鼠标交互绘制

发布时间 2023-08-31 16:53:07作者: 太一吾鱼水

html代码

 1 <!DOCTYPE html>
 2 <html lang="en">
 3   <head>
 4     <meta charset="utf-8" />
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
 6     <meta name="viewport"  content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
 7     <meta name="description" content="Draw point on terrain with mouse clicks.">
 8     <meta name="cesium-sandcastle-labels" content="Showcases">
 9     <title>Draw point</title>
10     <script type="text/javascript" src="Sandcastle-header.js"></script>
11       <script type="module" src="load-cesium-es6.js"></script>
12     <script src="./Build/CesiumUnminified/Cesium.js"></script>
13     <script>window.CESIUM_BASE_URL = "./Build/CesiumUnminified/";</script>
14   </head>
15   <body
16     class="sandcastle-loading"
17     data-sandcastle-bucket="bucket-requirejs.html"
18   >
19 <style>
20     @import url(bucket.css);
21         html,
22       body,
23       #cesiumContainer {
24       width: 100%;
25       height: 100%;
26       margin: 0;
27       padding: 0;
28       overflow: hidden;
29     }
30     </style>
31     <div id="cesiumContainer" class="fullSize"></div>
32     <div id="loadingOverlay"><h1>Loading...</h1></div>
33     <div id="toolbar">
34       <table class="infoPanel">
35         <tbody>
36           <tr>
37             <td>左键单击绘制点,右击结束线面绘制。</td>
38           </tr>
39         </tbody>
40       </table>
41     </div>
42     <script src="./code.js"> </script>
43 </body>
44 </html>

code.js代码

  1 Cesium.Ion.defaultAccessToken='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkNGNmNzRjYy0xNmZkLTQxNDEtYjQxMy0yMWI4NWE5ZWQwN2IiLCJpZCI6NTM1ODEsImlhdCI6MTYxOTI1NzU5MH0.Xcl8pPPUlgWmdip2hj90xyCoRz_Ikj7zCW1PgJhK2n8';
  2 window.startup = async function (Cesium) {
  3     'use strict';
  4     //增加视图区
  5     const viewer = new Cesium.Viewer("cesiumContainer", {
  6     selectionIndicator: false,
  7     infoBox: false,
  8     terrainProvider: Cesium.createWorldTerrain(),
  9     imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
 10                 url: "http://t0.tianditu.gov.cn/vec_w/wmts?tk=ec5a2a0e05d6e7be9aabdcfa8a8812a9" ,
 11                 layer: "vec",
 12                 style: "default",
 13                 tileMatrixSetID: "w",
 14                 format: "tiles",
 15                 maximumLevel: 18,
 16             }),
 17     });
 18 
 19     viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
 20     Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
 21     );
 22     function createPoint(worldPosition) {
 23         const point = viewer.entities.add({
 24             position: worldPosition,
 25             point: {
 26             color: Cesium.Color.RED,
 27             pixelSize: 5,
 28             heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
 29             },
 30         });
 31         return point;
 32     }
 33     let drawingMode = "line";
 34     function drawShape(positionData) {
 35         let shape;
 36         if (drawingMode === "line") {
 37             shape = viewer.entities.add({
 38             polyline: {
 39                 positions: positionData,
 40                 clampToGround: true,
 41                 material: Cesium.Color.RED,
 42                 width: 3,
 43             },
 44             });
 45         } else if (drawingMode === "polygon") {
 46             shape = viewer.entities.add({
 47             polygon: {
 48                 hierarchy: positionData,
 49                 material: new Cesium.ColorMaterialProperty(
 50                 Cesium.Color.RED.withAlpha(0.7)
 51                 ),
 52             },
 53             });
 54         }
 55         return shape;
 56     }
 57     let activeShapePoints = [];
 58     let activeShape;
 59     let floatingPoint;
 60     //窗口事件句柄
 61     const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
 62     handler.setInputAction(function (event) {
 63     const ray = viewer.camera.getPickRay(event.position);//根据鼠标点击坐标和相机坐标构建射线
 64     const earthPosition = viewer.scene.globe.pick(ray, viewer.scene);//射线与球面求交,在地面的交点
 65     // `earthPosition` will be undefined if our mouse is not over the globe.
 66     if (Cesium.defined(earthPosition)) //鼠标点击在地球范围内
 67     {
 68         if(drawingMode === "point"){
 69             createPoint(earthPosition);
 70         }
 71         else{
 72         if (activeShapePoints.length === 0) {
 73         floatingPoint = createPoint(earthPosition);
 74         activeShapePoints.push(earthPosition);
 75         const dynamicPositions = new Cesium.CallbackProperty(function () {
 76             if (drawingMode === "polygon") {
 77                 return new Cesium.PolygonHierarchy(activeShapePoints);
 78             }
 79             return activeShapePoints;
 80         }, false);//回调函数
 81         activeShape = drawShape(dynamicPositions);
 82         }
 83         activeShapePoints.push(earthPosition);
 84         createPoint(earthPosition);
 85     }
 86     }
 87     }, Cesium.ScreenSpaceEventType.LEFT_CLICK);//鼠标左键
 88 
 89     handler.setInputAction(function (event) {
 90     if (Cesium.defined(floatingPoint)) {
 91         const ray = viewer.camera.getPickRay(event.endPosition);
 92         const newPosition = viewer.scene.globe.pick(ray, viewer.scene);
 93         if (Cesium.defined(newPosition)) {
 94         floatingPoint.position.setValue(newPosition);
 95         activeShapePoints.pop();
 96         activeShapePoints.push(newPosition);
 97         }
 98     }
 99     }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);//鼠标移动
100     //移除临时绘制图像.
101     function terminateShape() {
102         activeShapePoints.pop();
103         drawShape(activeShapePoints);
104         viewer.entities.remove(floatingPoint);
105         viewer.entities.remove(activeShape);
106         floatingPoint = undefined;
107         activeShape = undefined;
108         activeShapePoints = [];
109     }
110     handler.setInputAction(function (event) {
111         terminateShape();
112     }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);//鼠标右键
113 
114     const options = [
115     {
116         text: "绘制线",
117         onselect: function () {
118         if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) {
119             window.alert(
120             "This browser does not support polylines on terrain."
121             );
122         }
123 
124         terminateShape();
125         drawingMode = "line";
126         },
127     },
128     {
129         text: "绘制面",
130         onselect: function () {
131         terminateShape();
132         drawingMode = "polygon";
133         },
134     },
135     {
136         text: "绘制点",
137         onselect: function () {
138         terminateShape();
139         drawingMode = "point";
140         },
141     },
142     ];
143 
144     Sandcastle.addToolbarMenu(options);
145     //缩放至点
146     viewer.camera.lookAt(
147         Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0),
148         new Cesium.Cartesian3(5000.0, 5000.0, 5000.0)
149     );
150     viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
151     //Sandcastle_End
152     Sandcastle.finishedLoading();
153 };
154 if (typeof Cesium !== 'undefined') {
155     window.startupCalled = true;
156     window.startup(Cesium).catch((error) => {
157       "use strict";
158       console.error(error);
159     });
160 }
View Code

效果: