Cesium实现自定义标签功能

Cesium实现自定义标签功能

实现的底层逻辑和方法跟实现Popup弹窗功能类似,只需要修改对应的创建的html内容和css样式,即可定义出更好看的标签。

实现效果

在这里插入图片描述

源码

LabelPlot 标签类


const defaultNameField = "label";
const defaultIdField = "id";
const billboardPointDatasourceName = "LABELPLOT_BILLBOARD_POINT"

/**
 * 标签类
 */
class LabelPlot {
  constructor(info) {
    let _this = this;
    _this.viewer = info.viewer; //弹窗创建的viewer
    _this.geometry = info.position; //弹窗挂载的位置
    _this.properties = info.properties; // 属性信息
    if (!info || !info.viewer || !info.position) {
      throw new Error("缺少构造参数!");
    }

    let labelPlotId = _this._getKeyVal(info.properties,defaultIdField);
    if (!labelPlotId) {
      labelPlotId = "LabelPlot_" + (new Date().getTime() + Math.random() + '').replace('.', '');
    }
    _this.id = labelPlotId;

    _this.ctn = $("<div class='LabelPlot-container' id =  '" + _this.id + "'>");
    $(_this.viewer.container).append(_this.ctn);
    _this.ctn.append(_this._createHtml(info.properties));
    //生成底座小圆点
    if (!!info.showBillboardPoint) {
      _this.entity = _this._createBillboardPoint(info.position);
    }
    try {
      _this._render(_this.geometry);
      _this.eventListener = _this.viewer.clock.onTick.addEventListener(function (clock) {
        _this._render(_this.geometry);
      })
    } catch (e) {

    }
  }

  //关闭当前标签
  close() {
    let _this = this;
    _this.ctn.remove();
    _this.viewer.clock.onTick.removeEventListener(_this.eventListener);
    if (_this.entity) {
      let myEntityCollection = _this._getBillboardPointEntityCollection();
      myEntityCollection.entities.remove(_this.entity);
    }
  }

  //清除所有的小圆点
  static clearBillboardPointEntityCollection(){
    let dats = Viewer.dataSources.getByName(billboardPointDatasourceName);
    if (!!dats && !!dats.length) {
      dats.forEach(item => {
        Viewer.dataSources.remove(item);
      })
    }
  }

  _render(geometry) {
    let _this = this;
    let position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(_this.viewer.scene, geometry);
    if (position) {
      _this.ctn.css("left", position.x);
      _this.ctn.css("top", position.y - _this.ctn.get(0).offsetHeight - 85);
      //摄像头高度超过一定值,标签隐藏
      /*let cameraHeight = _this.viewer.camera.positionCartographic.height;
      if (cameraHeight > 50000) {
        _this.ctn.hide();
      } else {
        _this.ctn.show();
      }*/
    }
  }

  //生成标签
  _createHtml(properties) {
    let _this = this;
    let labelName = _this._getKeyVal(properties,defaultNameField);
    labelName = !!labelName ? labelName : "";
    let html = '<div class="LabelPlot-content">' +
      '<div class="info-item">'+ labelName +'</div></div>';
    return html;
  }

  //生成底下的小圆点
  _createBillboardPoint(position) {
    let _this = this;
    let myEntityCollection = _this._getBillboardPointEntityCollection();
    let entityOption = {
      name: "LABELPLOT_BILLBOARD_POINT_ENTITY",
      position: position,
      point: { //点
        color: Cesium.Color.DARKBLUE.withAlpha(.4),
        pixelSize: 6,
        outlineColor: Cesium.Color.YELLOW.withAlpha(.4),
        outlineWidth: 2,
        // scaleByDistance: new Cesium.NearFarScalar(300, 1, 1200, .4),
        // disableDepthTestDistance: 500
      }
    }
    let entity = new Cesium.Entity(entityOption);
    if (entity && myEntityCollection) {
      myEntityCollection.entities.add(entity);
    }
    return entity;
  }

  _getKeyVal(data,keyName) {
    let keyVal = null;
    if (!!data && !!keyName && !!Object.keys(data).length) {
      let keys = Object.keys(data);
      for (let index = 0 ; index < keys.length;index++) {
        if (keys[index].toLowerCase() === keyName) {
          keyVal = data[keys[index]];
          break;
        }
      }
    }
    return keyVal;
  }
  _getBillboardPointEntityCollection() {
    let _this = this;
    let myEntityCollection = null;
    let dats = _this.viewer.dataSources.getByName(billboardPointDatasourceName);
    if (!dats || !dats.length) {
      myEntityCollection = new Cesium.CustomDataSource(billboardPointDatasourceName);
      _this.viewer.dataSources.add(myEntityCollection);
    } else {
      myEntityCollection = dats[0];
    }
    return myEntityCollection;
  }
}

export default LabelPlot;

css样式


.LabelPlot-container {
  background: rgba(227,238,229,.62);
  position: absolute;
  z-index: 999;
}

.LabelPlot-content {
  left: 0;
  bottom: 0;
  cursor: default;
  padding: 5px;
  border: 1px solid rgba(156,153,68,.91);
}

.LabelPlot-container:before {
  position: absolute;
  content: "";
  left: 0%;
  bottom: -80px;
  height: 80px;
  border-left: 2px dashed rgba(197,226,39,.44);
}

调用示例

let labelPlotList = [];
 let handler3D = new Cesium.ScreenSpaceEventHandler(Viewer.scene.canvas);
      handler3D.setInputAction(function (click) {
        let pick = new Cesium.Cartesian2(click.position.x, click.position.y);
        if (pick) {
          // 获取点击位置坐标
          let cartesian = Viewer.scene.globe.pick(Viewer.camera.getPickRay(pick), Viewer.scene);
          if (cartesian) {
            //生成标签
            let labelPlot = new LabelPlot({
              viewer: Viewer,
              position: cartesian,
              properties: {
                id: 'ilabel-'+new Date().getTime()+Math.random(),   
                label: 'ilabel-'+new Date().getTime()+Math.random(), 
              },
              showBillboardPoint: true
            })
            labelPlotList.push(labelPlot);
          }
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

//清除标签
if (!!labelPlotList && labelPlotList.length) {
 labelPlotList.forEach(ee=>{
    ee.close();
  })
}
labelPlotList = [];
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值