Cesium的打点分为两类:

  1. 通过Entity(实体)来打点
  2. 通过geometry(几何图形)来打点

在实际应用中,需要对各种点进行定制化的话,可以通过Entity中的billboard(广告牌)引入图片来进行点处理,故大多数使用Entity。本文主要介绍使用实体打点的两种方式,point和billboard。

1. 打点

首先创建一个cesium实例,并创建一个point实体和一个billboard实体:

  1. //Map.vue
  2. <template>
  3. <div id="map"></div>
  4. </template>
  5. <script>
  6. import "cesium/Build/Cesium/Widgets/widgets.css";
  7. import { Viewer, Cartesian3, Entity } from 'cesium';
  8. export default {
  9. mounted() {
  10. const defaultCesiumConifg = {
  11. geocoder: false, //查找位置工具
  12. homeButton: false, //返回初始位置按钮
  13. sceneModePicker: false, //视角选择器
  14. baseLayerPicker: false, //图层选择器
  15. navigationHelpButton: false, //导航帮助按钮
  16. animation: false, //动画控制器
  17. timeline: false, //时间线
  18. fullscreenButton: false, //全屏控制
  19. };
  20. const viewer = new Viewer('map', defaultCesiumConifg);
  21. viewer._cesiumWidget._creditContainer.style.display = "none"; //关闭版权声明
  22. viewer.infoBox.destroy(); //关闭实体点击是默认显示的信息盒子
  23. viewer.selectionIndicator.destroy(); //关闭实体点击时,实体的选择指示器
  24. //创建一个外圈红色,内圈白色的点
  25. viewer.entities.add(new Entity({ //此处建议使用new Entity的方式,方便编辑器进行类型推导,不使用它也会自动转化为entity类
  26. position: Cartesian3.fromDegrees(111.4, 40.4), //经纬度位置转化
  27. point: {
  28. pixelSize: 30,
  29. color: Color.WHITE,
  30. outlineColor: Color.RED,
  31. outlineWidth: 5,
  32. },
  33. }));
  34. //添加带图片类型的点
  35. viewer.entities.add(new Entity({
  36. position: Cartesian3.fromDegrees(-111.6, 40.6),
  37. billboard: {
  38. image: '/01.png', //图片路径
  39. width: 30,
  40. height: 30,
  41. }
  42. }));
  43. }
  44. }
  45. </script>

实体信息盒子和选择指示器未关闭时,显示如下: image.png

两个打点的效果如下:
image.png

2. 气泡弹窗

在map中添加一个div,id为popup,并在初始化好的Entity后面添加点击事件。

  1. <template>
  2. <div id="map">
  3. <div id="popup"></div>
  4. </div>
  5. </template>
  6. <script>
  7. import {ScreenSpaceEventHandler, ScreenSpaceEventType, } from 'cesium';
  8. ...
  9. //点击显示气泡
  10. const handler = new ScreenSpaceEventHandler(viewer.scene.canvas); //获取事件处理器
  11. const scene = viewer.scene;
  12. const popup = document.querySelector('#popup');
  13. popup.style.display = 'none'; //设置气泡为不可见,也方便进行变量查询
  14. let entity; //声明被点击的实体变量
  15. handler.setInputAction(event => { //注册画布点击事件
  16. const clickPoint = scene.pick(event.position); //设置拾取点,如果点击处有实体,返回拾取对象,否则返回undefined
  17. if(clickPoint && viewer.entities.contains(clickPoint.id)) { //判断实体是否存在
  18. entity = clickPoint.id; //实体获取
  19. //气泡的显示以及位置设置
  20. popup.style.display = 'block';
  21. popup.style.left = event.position.x - 200 + 'px';
  22. popup.style.top = event.position.y -350 + 'px';
  23. }
  24. }, ScreenSpaceEventType.LEFT_CLICK);
  25. //气泡跟随实体点的移动而移动
  26. scene.postRender.addEventListener(() => { //渲染事件监听
  27. if(popup.style.display !== 'none') { //气泡已经被点击显示的时候触发
  28. //将实体的坐标系位置转化为当前窗口位置
  29. const entityPos = SceneTransforms.wgs84ToWindowCoordinates(scene, entity.position._value);
  30. popup.style.top = entityPos.y - 350 + 'px';
  31. popup.style.left = entityPos.x - 200 + 'px';
  32. }
  33. });
  34. </script>
  35. <style>
  36. #popup {
  37. width: 400px;
  38. height: 300px;
  39. }
  40. </style>

实现效果如下,且随着三维球的运动,弹窗也会随之移动:
image.png

拾取到实体的对象数据结构 image.png 实体内position结构 image.png

参考资料: