欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(六)关于cesium地图的使用:拖拽圆实现

程序员文章站 2022-05-27 16:25:09
...

业务逻辑

以某个中心点画出默认半径的圆形区域,可手动拖动圆形,改变半径大小,进而查询圆形区域内存在资源情况。

1、在data中定义需要的变量
data(){
	return{
		dragState: false,	 	// 拖拽状态
		centerLonlat: [], 		// 拖拽中心点  
		 redCircle: null, 		// 拖拽圆实体对象
		 distance: 2000,	    // 拖拽距离
		 redLine: null, 		// 拖拽圆线
		 redLabel: null, 		// 拖拽按钮上的文本
		 dragMarker: null, 		// 拖拽按钮
         dragCallback: '', 		// 拖拽回调函数
	}
}
2、在method中定义setCircle,画拖拽圆实现方法
// 画拖拽圆实现方法
setCircle(){
	let distance = this.distance;	// 半径
	this.centerLonlat = this.currMarker.database.lonlat;	// 初始化中心点位置
	// 计算经度(用于计算拖拽点实体上图位置)
    this.dragLon = this.centerLonlat[0] + this.meter2Lng(distance, this.centerLonlat[1]);
    // 画圆
    window.viewer.entities.remove(this.redCircle);	// 先删除已有的圆形实他,重新画圆
    this.redCircle = window.viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(
            this.centerLonlat[0],
            this.centerLonlat[1]
        ),
        ellipse: {
            semiMajorAxis: distance,
            semiMinorAxis: distance,
            height: 0,
            material: Cesium.Color.fromCssColorString(
                '#0078ff'
            ).withAlpha(0.3),
            outline: true,
            outlineColor: Cesium.Color.fromCssColorString('#00bfff'),
        },
    });
    
   // 画线
   if (!this.polylines) {
       this.polylines = window.viewer.scene.primitives.add(
           new Cesium.PolylineCollection()
       );
   } else {
       this.polylines.remove(this.redLine);
   }
   this.redLine = this.polylines.add({
       positions: new Cesium.Cartesian3.fromDegreesArray([
           this.centerLonlat[0],
           this.centerLonlat[1],
           this.dragLon,
           this.centerLonlat[1],
       ]),
       material: new Cesium.Material.fromType(
           Cesium.Material.PolylineDashType,
           {
               color: Cesium.Color.fromCssColorString('#00bfff'), //线条颜色
               gapColor: Cesium.Color.TRANSPARENT, //间隔颜色
               dashLength: 20, //短划线长度
           }
       ),
       width: 1,
   });

	// 文本
	window.viewer.entities.remove(this.redLabel);
		this.redLabel = window.viewer.entities.add({
		   position: Cesium.Cartesian3.fromDegrees(
		       this.centerLonlat[0] +
		           this.meter2Lng(distance, this.centerLonlat[1]),
		       this.centerLonlat[1],
		       1
		   ),
		   label: {
		       text:
		           distance < 1000
		               ? distance.toFixed(0) + 'm'
		               : (distance / 1000).toFixed(2) + 'km',
		       font: '16px sans-serif',
		       pixelOffset: new Cesium.Cartesian2(30, -20),
		   },
	});
	
	// 拖拽点
    window.viewer.entities.remove(this.dragMarker);
    let marker = {
        markerType: 'dragBtn',
        position: Cesium.Cartesian3.fromDegrees(
            this.dragLon,
            this.centerLonlat[1],
            0
        ),
        billboard: {
            //图标
            image: require('../assets/image/warning/drag_icon.png'),
            width: 39,
            height: 20,
            pixelOffset: Cesium.Cartesian2.ZERO,
            eyeOffset: Cesium.Cartesian3.ZERO,
            heightReference: Cesium.HeightReference.NONE,
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
            verticalOrigin: Cesium.VerticalOrigin.CENTER,
        },
    };
    this.dragMarker = window.viewer.entities.add(marker);
}

/**
 * 距离(米)转换为经度 不同纬度下一米对应的经度不同
 * @param { Number } meter 距离多少米
 * @param { Number } lat 所在纬度
 * @returns { Number }
 */
meter2Lng(meter, lat) {
    if (!meter || !lat) {
        throw new Error('Error in Parameter!');
    }
    let pi = Math.PI;
    let latInMeter = (Math.cos((lat * pi) / 180) * 6371 * 2 * pi) / 360;
    return meter / latInMeter / 1000;
},
3、监听拖拽点事件,动态画出圆形区域
addMouseListener() {
	let that = this;
    const handler = new Cesium.ScreenSpaceEventHandler(
        window.viewer.scene.canvas
    );
    handler.setInputAction(function (movement) {
    	// 拖拽状态
         if (that.dragState) {
             const ellipsoid = window.viewer.scene.globe.ellipsoid;
             let cartesian = window.viewer.camera.pickEllipsoid(
                 movement.endPosition,
                 ellipsoid
             );
             let cartographic = ellipsoid.cartesianToCartographic(
                     cartesian
                 ),
                 longitudeString = Cesium.Math.toDegrees(
                     cartographic.longitude
                 ),
                 latitudeString = Cesium.Math.toDegrees(
                     cartographic.latitude
                 );
             // 计算距离
             let startCartographic = Cesium.Cartographic.fromDegrees(
                 that.centerLonlat[0],
                 that.centerLonlat[1]
             );
             let endCartographic = Cesium.Cartographic.fromDegrees(
                 Number(longitudeString),
                 Number(latitudeString)
             );
             let geodesic = new Cesium.EllipsoidGeodesic();
             geodesic.setEndPoints(startCartographic, endCartographic);
             that.dragLon = Number(longitudeString);
             that.distance = geodesic.surfaceDistance;

             that.setCircle();
         }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
	
	// 鼠标抬起
    handler.setInputAction((movement) => {
        const pickedObject = window.viewer.scene.pick(
            movement.position
        );
        if (this.dragState) {
            this.dragCallback();  
            window.viewer.scene.screenSpaceCameraController.enableRotate = true;
            this.dragState = false;
        }
    }, Cesium.ScreenSpaceEventType.LEFT_UP);
}
4、dragCallback中描述拖拽后的处理逻辑
dragCallback(){
	// 一般是根据半径距离的变化查询新的数据
	......
}
相关标签: CesiumJs地图