一、点位上图
①在Cesium中,每个自定义的地图元素被视为一个entity对象,如果我们要添加点位到地图上,那就必须先创建一个entity对象。
var entity = new Cesium.Entity({
  position: position,
});
以上代码我们创建了一个entity对象,只需要给予一个坐标参数就可以创建成功。
②但是,仅仅只是一个坐标点在一般情况下是没办法满足我们的需求的,大多数时候我们都需要为我们的点位添加一个icon图标或者点位作为指示。这里就需要用到它另外一个参数,billboard。
// 若是没有配置billboard并且不把这个参数设置为undefined,则可能会显示系统自带的billboard。
var billboard = new Cesium.BillboardGraphics({
  image: 'path/to/image.png',
  scale: 1.0,
  width: 30, // 图标的宽度
  height: 30, // 图标的高度
  depthTest: false, // 禁用深度测试
  disableDepthTestDistance: Number.POSITIVE_INFINITY, // 禁用深度测试
  // 调整图标的位置
  pixelOffset: {
       x: 0,
        y: -12
  }
});
entity.billboard = billboard 
③有时候我们还想在点位图标下方添加简短的文本名称,这个时候可以使用label这个参数
var label = new Cesium.LabelGraphics({
    text: entity.name,
    scale: 0.5,
    pixelOffset: new Cesium.Cartesian2(0, 15), // 调整文本位置偏移
    horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
    fillColor: Cesium.Color.WHITE,
    outlineColor: Cesium.Color.BLACK,
    outlineWidth: 1.0,
    style: Cesium.LabelStyle.FILL_AND_OUTLINE
});
entity.label = label
④至此,常用的点位设置已经完成,最后把点位加到地图中,大功告成。
viewer.entitys.add(entity)

二、点击弹窗
地图上加了点位之后,虽然显得没那么单调了,但是如果我们跟地图的互动仅仅只有拖动缩放,那可能也是相对死板无趣的,这个时候就可以考虑多添加一些交互事件,譬如点击图标的时候出现弹窗。
这里稍微讲一下加入弹窗的方法和原理。
我们没办法像插入点位那样,把我们的弹窗写成entity直接插入到地图内部,因为entity说到底也是有一定限制的,它大概率不能符合我们插入弹窗的需求。
那既然没办法从内部攻破,我们就在外部进行操作,让弹窗看起来好像就是在地图内部中。
总结起来就是:
1、在浏览器的视图中用绝对定位加入我们的弹窗html元素
 2、定义每次点击地图触发的事件,获取到相关经纬度数据,并且判断是否点击到了点位。
 3、若是判断是点击到了点位,那么我们就可以获取到点击到的entity的信息。拿到这个信息就可以把对应信息显示在弹窗上。
 4、拿到entity的信息里面有经纬度的信息,我们需要把经纬度信息转化成浏览器视图中x,y坐标,这样就可以根据这个坐标来定位我们的弹窗,让弹窗显示在对面点位上方。
 5、监听地图的缩放和拖动事件,时刻去改变已显示弹窗的位置,达到视角如何变化,弹窗依旧处于点位上方的效果。
①首先要明白,cesium没有让你把弹窗插到它组件内的渠道,所以我们需要在html代码中添加我们自己的弹窗,还可以自定义样式。
<div class="info_box" ref="infoBox" id="infobox">
      <div class="info_title">
        <img src="../../assets/images/map/u93.svg" alt="" />
        <p>{{ modalData.name }}</p>
        <i class="el-icon-close" @click="closeInfoBox"></i>
      </div>
      <div class="info_body">
        <img src="../../assets/images/map/u94.svg" alt="" />
        <div class="info_content">
          <div
            class="content_line"
            v-for="(val, key, i) in modalData"
            :key="i"
            v-if="key != 'name'"
          >
            <p class="text">{{ key }}</p>
            <p class="val">{{ val }}</p>
          </div>
        </div>
      </div>
    </div>
②上面的代码看看就行了,是我个人的弹窗代码,各位可以根据自己的需求写一个弹窗和弹窗样式。接下来我们可以创建一个infobox对象,这个是cesium自带的对象,可以让我们控制html页面元素的属性。
this.infoBox = new Cesium.InfoBox(document.getElementById("infobox"));
③监听地图点击事件,判断是否点击到了点位。
// 监听 Viewer 的 pick 事件
    this.viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
      // 获取点击的位置
      var pickedObject = that.viewer.scene.pick(movement.position);
      // 判断是否选中了一个实体
      if (Cesium.defined(pickedObject) && pickedObject.id instanceof Cesium.Entity) {
        var entity = pickedObject.id;
        if (entity.position) {
          // 显示弹窗
          that.infoBox.container.style.visibility = 'visible';
          // 获取位置信息
          that.entityPosition = entity.position.getValue(that.viewer.clock.currentTime);
          // 传递数据,由于我定义了一个map.js文件,所以没办法把点位数据直接传递给页面,只能用eventBus传递两个文件的数据
          eventBus.$emit('data-changed', entity.properties)
        } else {
          that.infoBox.container.style.visibility = 'hidden';
        }
      } else {
        // 隐藏弹窗
        that.infoBox.container.style.visibility = 'hidden';
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
④监听拖动和缩放事件,并且时时改变弹窗位置,让弹窗不管如何都一直在点位上方。(这里要注意弹窗元素的层级问题,z-index)
// 监听 Viewer 的 postRender 事件,在地图移动时更新弹窗位置
    this.viewer.scene.postRender.addEventListener(function () {
      try {
        if (that.entityPosition !== null) {
          that.modalSetting()
        }
      } catch (error) {
        console.log(error)
      }
    });
// 弹窗位置设置事件
  modalSetting() {
    let screenPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, this.entityPosition);
    if (screenPosition) {
      let leftOffset = screenPosition.x - this.infoBox.container.clientWidth / 2 + 225;
      let topOffset = screenPosition.y - this.infoBox.container.clientHeight - 20;
      this.infoBox.container.style.left = leftOffset + 'px';
      this.infoBox.container.style.top = topOffset + 'px';
    }
  }

三、为什么我的点位图标那么模糊?
这是因为cesium像素的设置问题,这里只需要几行代码设置便可以切换到高清画质。
this.viewer.scene.fxaa = false
this.viewer.scene.postProcessStages.fxaa.enabled = false
if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) { //判断是否支持图像渲染像素化处理
  this.viewer.resolutionScale = window.devicePixelRatio;
}



















