cesium常用功能封装组件

9 篇文章 0 订阅
1 篇文章 0 订阅

cesium的下载和安装,这里就不做赘述了,大家可自行查找,实在找不到的话可以给我留言.

这里封装的cusium组件,主要功能包括:地图加载、扎点 、画线、叠加图层、监听鼠标聚焦和点击事件并给出相应的回调。


<template>
  <div class="cesiumMap">
    <div :id="mapConfig.mapBoxId" class="fullSize"></div>
    <!-- 弹窗dom -->
    <div
      v-show="mapConfig.popupBoxShow"
      :id="mapConfig.popupBoxId"
      class="ol-popup"
    >
      <slot :markerInfo="markerInfo"></slot>
      <!-- <slot name="mouseMove" :markerInfo="markerInfo"></slot>
      <slot name="mouseClick" :markerInfo="markerInfo"></slot> -->
    </div>
  </div>
</template>
<script>
import { addWmtsLayer } from "./addWmts";
import overLayer from "./overLayer";
let TileMapServiceImageryProvider = null;
const DEFAULT_CONFIG = {
//定义地图服务地址
  DEFAULT_PMTS_URL:"http://xxxxxxxxxxx",
  DEFAULT_WETS_URL:"http://xxxxxxxxxxxxxxxxx",
  DEFAULT_WMTS_URL:"http:XXXxxxxxxxxxxx",
};
let mapViewer = null; //定义地图容器
let markerLayer = null;
let tileset = null;
let onMouseClick = null; //鼠标点击监听事件
let currOverlay = null; //弹窗图层
export default {
  name: "MapCesium",
  props: {
    //  地图个性化配置,在父组件内调用该组件时根据需要传值
    mapConfig: {
      type: Object,
      default: () => {
        return {
          mapBoxId: "mapId",
          popupBoxId: "",
          popupOffset: {
            //弹窗距点位的偏移量
            x: 0,
            y: 0,
          },
          needPointClickCallback: false, //是否需要点击扎点的回调
          showLabelText: false, //是否显示图标旁的文字
          textName: "", //要显示的文字的取值字段名
          textOffset: 0, ///要显示的文字偏移量
          needMouseClickHandler: false, //是否需要监听鼠标点击事件
          needMouseMoveHandler: false, //是否需要监听鼠标移动事件
          popupBoxShow: false, //默认不显示弹框
          initCenter: {}, //初始化地图中心
          needFocusChange:true
        };
      },
    },
    //打点数据
    pointList: {
      type: Array,
      default: function () {
        return [];
      },
    },
  },
  data() {
    return {
      tileset: null,
      TileMapServiceImageryProvider: null,
      pointInfo: {},
      markerInfo: {},
      initLoad: true,
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.initMap();//初始化加载地图
    });
  },
  methods: {
    initMap() {
      let serviceUrl = DEFAULT_CONFIG.DEFAULT_PMTS_URL;
      let wmtsUrl = DEFAULT_CONFIG.DEFAULT_WMTS_URL;
      mapViewer = new Cesium.Viewer(this.mapConfig.mapBoxId, {
        imageryProvider: new Cesium.TileMapServiceImageryProvider({
          url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"),
        }),
        geocoder: false, //是否显示地名查找控件
        homeButton: false,
        sceneModePicker: false, //是否显示投影方式控件
        baseLayerPicker: false, //是否显示图层选择控件
        navigationHelpButton: false, //是否显示帮助信息控件
        animation: false, //是否显示动画控件(左下方那个)
        timeline: false, //是否显示时间线控件
        fullscreenButton: false,
        vrButton: false,
        infoBox: false, //去除原生自带右上角弹窗
        selectionIndicator: false, //点击球体显示绿色标识框
      });
      // mapViewer.scene.screenSpaceCameraController.minimumZoomDistance = 20;
      // mapViewer.scene.screenSpaceCameraController.maximumZoomDistance = 2000;
      // mapViewer.clock.shouldAnimate = true;
      // mapViewer.clock.multiplier = 20000;
      // mapViewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
      //拉取3维地图资源
      tileset = new Cesium.Cesium3DTileset({
        url: serviceUrl,
      });
      tileset.readyPromise
        .then(function (tileset) {
          mapViewer.scene.primitives.add(tileset);
          mapViewer.zoomTo(
            tileset,
            new Cesium.HeadingPitchRange(
              0.0,
              -0.5,
              tileset.boundingSphere.radius * 2.0
            )
          );
        })
        .otherwise(function (error) {
          console.log(error);
        });
      // WMTS二维底图
      addWmtsLayer(mapViewer, {
        url: wmtsUrl,
        autoFly: true,
      });
      // 鼠标监听事件
      if (this.mapConfig.needMouseClickHandler || false) {
        this.addMouseClickHandler();
      }
      if (this.mapConfig.needMouseMoveHandler || false) {
        this.addMouseMoveHandler();
      }
    },
    //监听鼠标点击事件
    addMouseClickHandler() {
      onMouseClick = new Cesium.ScreenSpaceEventHandler(mapViewer.canvas);
      onMouseClick.setInputAction((event) => {
        let marker = mapViewer.scene.pick(event.position);
        if (!marker || marker.id._id == -1) {
          console.log("点击的内容不是一个点位");
          return;
        }
        if (currOverlay) {
          currOverlay.close();
        }
        this.markerInfo = this.pointList.find((i) => marker.id._id == i.id);
        if (!this.markerInfo) {
          console.log("获取不到点位的信息");
          return;
        }
        //父组件是否需要点击地图的回调事件
        if (this.mapConfig.needPointClickCallback) { 
          this.$emit("clickPointCallback", this.markerInfo); 
        }
        //是否需要点击扎点位置后,在扎点位置弹窗显示内容
        if(this.mapConfig.popupBoxId){
          // 只有设置了popupBoxId才会新增图层
          let element = document.getElementById(this.mapConfig.popupBoxId);
          let position = Cesium.Cartesian3.fromDegrees(
            this.markerInfo.longitude * 1,
            this.markerInfo.latitude * 1,
            this.markerInfo.floorHeight || 30
          );
          let id = marker.id;
          this.addOverlay(element, position, id);
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

      //这里的事件类型有:
      // LEFT_DOWN,LEFT_UP,LEFT_CLICK,LEFT_DOUBLE_CLICK
      // RIGHT_DOWN,RIGHT_UP,RIGHT_CLICK
      // MIDDLE_DOWN,MIDDLE_UP,MIDDLE_CLICK,MOUSE_MOVE,WHEEL
    },
    //监听鼠标移动事件
    addMouseMoveHandler() {
      onMouseClick = new Cesium.ScreenSpaceEventHandler(mapViewer.canvas);
      onMouseClick.setInputAction((event) => {
        let marker = mapViewer.scene.pick(event.endPosition);
        if (marker) {
          this.markerInfo = this.pointList.find((i) => marker.id._id == i.id);
          if (!this.markerInfo) {
            console.log("获取不到点位的信息");
            return;
          }
          //点击点位的回调
          let element = document.getElementById(this.mapConfig.popupBoxId);
          let position = Cesium.Cartesian3.fromDegrees(
            this.markerInfo.longitude * 1,
            this.markerInfo.latitude * 1,
            this.markerInfo.floorHeight || 30
          );
          let id = this.markerInfo.id;
          this.addOverlay(element, position, id);
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    },
    // 添加点数据
    addMarkers(markers) {
      mapViewer.entities.removeAll();
      markers.map((item, index) => {
        //地图扎点时每个点的信息如下:
        let iconWidth = item.iconWidth || 40;
        let iconHeight = item.iconHeight || 40;
        let longitude = item.longitude;
        let latitude = item.latitude;
        let floorHeight = item.floorHeight || 50; //高度默认0
        let icon = item.icon || null;
        if (longitude && latitude) {
          mapViewer.entities.add({
            name: "build",
            id: item.id,
            position: Cesium.Cartesian3.fromDegrees(
              longitude,
              latitude,
              floorHeight // TODO: 高程未知,暂设置为地面高程
            ),
            // 打点图标
            billboard: {
              image: icon,
              width: iconWidth,
              height: iconHeight,
            },
            //文字标签
            label:
              this.mapConfig.showLabelText || false
                ? this.getText(`${item[this.mapConfig.textName]}`)
                : null,
            // pixelOffset: new Cesium.Cartesian2(16, -39),
            // 默认值为0,0,默认所加载的图片的中心位置与撒点坐标叠在一起, 此参数用于调整图片的哪个点和撒点位置重合
            // 第一个参数为往屏幕右边平移的像素值,第二个参数为往屏幕下方平移的参数值
          });
        }
      });
      //切换中心点
      let longitude = "";
      let latitude = "";
      let floorHeight = "";
      if (
        this.mapConfig.initCenter &&
        this.mapConfig.initCenter.latitude &&
        this.initLoad
      ) {
        //指定初始化中心点坐标
        longitude = this.mapConfig.initCenter.longitude ;
        latitude = this.mapConfig.initCenter.latitude ;
        this.initLoad = false;
        mapViewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, 800),
        });
       //800为视野高度,数字越大视野范围越广
      } else if (this.mapConfig.needFocusChange && markers[0].longitude && markers[0].latitude) {
        //不指定中心点,取第一个坐标点作为中心点
        longitude = markers[0].longitude ;
        latitude = markers[0].latitude ;
        mapViewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, 7500),
        });
      }
    },
     //添加弹窗图层
    addOverlay(element, position, id) {
      //销毁当前弹出的浮云框
      if (currOverlay) {
        currOverlay.close();
      }
      let option = {
        id: id,
        element: element,
        position: position,
        offset: {
          //默认整个div的【左下角】,跟地图上指定的点重合
          x: this.mapConfig.popupOffset ? this.mapConfig.popupOffset.x : 0, //向屏幕左边平移的像素值
          y: this.mapConfig.popupOffset ? this.mapConfig.popupOffset.y : 0, //向屏幕下方平移的像素值
        },
      };
      currOverlay = new overLayer(option);
      mapViewer.addOverlay(currOverlay);
      currOverlay.setPosition(position);
    },
    //获取可配置的文字内容
    getText(text) {
      return {
        show: this.mapConfig.showLabelText,
        text: text,
        font: "500 30px Helvetica", // 15pt monospace
        scale: 0.5,
        style: Cesium.LabelStyle.FILL,
        fillColor: Cesium.Color.WHITE,
        pixelOffset: new Cesium.Cartesian2(this.mapConfig.textOffset * 2, 0), //偏移量
        showBackground: true,
      };
    },
    //画线
    AddPolyline(polylineInfo) {
        if(polylineInfo.positions.length === 0){
            this.$message.warning('无轨迹路线');
            return;
        }
        let positions=Cesium.Cartesian3.fromDegreesArray(polylineInfo.positions);
        mapViewer.entities.removeById("polylineId");
        mapViewer.entities.add({
            id: "polylineId",
            name:polylineInfo.name || '线',
            show:true,
            polyline:{
                show:true,
                positions: positions,
                width:polylineInfo.width || 3,
                material: new Cesium.PolylineDashMaterialProperty({
                    color: Cesium.Color.RED
                }),
                clampToGround: true
            }
        });
    },
    //添加图片
    addHeatMap(markers){
      var latMax = 36.12552698032415;
      var latMin = 36.0654854;
      var lonMax = 120.48212;
      var lonMin = 120.4137071;
      mapViewer.entities.removeById("heatmapId");
      mapViewer.entities.add({
        name: 'heatmap',
        id:"heatmapId",
        rectangle: {
          coordinates: Cesium.Rectangle.fromDegrees(lonMin, latMin, lonMax, latMax),
          material: new Cesium.ImageMaterialProperty({
              image: require("@/assets/images/streetCloudImg/home/heatMap.png"),
              width:112,
              height:56,
              transparent: false
          })
         }
       })
    },
    //弹窗关闭事件
    closePopup() {
      if (currOverlay) {
        currOverlay.close();
      }
    },
  },
};
</script>
<style scoped lang="scss">
.cesiumMap {
  height: 100%;
  width: 100%;
  .fullSize {
    height: 100%;
    width: 100%;
  }
}
.ol-popup {
  // width: 289px;
  min-width: 289px;
  height: 180px;
  position: absolute;
  top: 0; //默认顶部不占高度
}
</style>
	

父组件调用:

其中mapConfig内的配置项可参考封装组件内的备注自行添加.pointList是扎点坐标list

    <map-cesium
      ref="cesiumMap"
      :mapConfig="mapConfig"
      :pointList="pointList"
      @clickPointCallback="clickPointCallback"
      v-slot="slotProps"
    >
      <div class="popupBox">
        <div class="popupInfo">
          <span class="title">设备名称</span
          ><span class="info">{{ slotProps.markerInfo.deviceName }}</span>
        </div>
        <div class="popupInfo">
          <span class="title">设备类型</span
          ><span class="info">{{ slotProps.markerInfo.deviceType }}</span>
        </div>
      </div>
    </map-cesium>

以上,时间较紧张写的比较粗糙,大家有什么问题可以给我留言,或者我的代码里有哪个不太好的地方,也欢迎大家补充,一起交流学习.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值