Cesium(八)小地图与实时显示位置

之前搜罗一堆资料,发现有个老哥用两个viewer实现了类似小地图的功能,但是我尝试了一下发现性能方面好像不太友好。而且里面是个球体,就算可以隐藏地球,但是一切都变得复杂了,而我只需要一个二维地图就行了。

Cesium(八)小地图与实时显示位置_第1张图片

思路

1.创建小地图
2.小地图上绘制点
3.根据坐标修改点的位置
4.如何监听坐标的改变

创建小地图

我这里使用的mapboxgl,我很喜欢里面的自定义地图样式,用别的应该可以可以的,比如leaflet,但是我就没去试了。

            mapboxgl.accessToken = 'token';
            var map = new mapboxgl.Map({
     
            container: 'map', // div的id
            style: '', //自定义样式
            center: [109.608275784, 18.3086668], // 开始的中心位置
            zoom: 16 // 开始的缩放倍数
            });

小地图上绘制点

这里如果不加on,load就会报错的,说什么样式还没加载完.

var _this = this
      map.on('load', function () {
     
          map.addSource("polygon",
           _this.createDot([109.608275784, 18.3086668], 0.01));//0.01是点的大小

          map.addLayer({
     
              "id": "polygon",
              "type": "fill",
              "source": "polygon",
              "layout": {
     },
              "paint": {
     
                  "fill-color": "blue",
                  "fill-opacity": 0.6,
              }
          });
      })
      //这个方法是看了哪个老哥的帖子,现在找不到了。。
      createDot(center, radiusInKm, points){
     
	     if(!points) points = 64;
	     var coords = {
     
	         latitude: center[1],
	         longitude: center[0]
	     };
	     var km = radiusInKm;
	     var ret = [];
	     var distanceX = km/(111.320*Math.cos(coords.latitude*Math.PI/180));
	     var distanceY = km/110.574;
	     var theta, x, y;
	     for(var i=0; i<points; i++) {
     
	         theta = (i/points)*(2*Math.PI);
	         x = distanceX*Math.cos(theta);
	         y = distanceY*Math.sin(theta);
	         ret.push([coords.longitude+x, coords.latitude+y]);
	     }
     ret.push(ret[0]);
      return {
     
          "type": "geojson",
          "data": {
     
              "type": "FeatureCollection",
              "features": [{
     
                  "type": "Feature",
                  "geometry": {
     
                      "type": "Polygon",
                      "coordinates": [ret]
                  }
              }]
          }
      };
  }

我这里还有一个插入图片的方法,大家可以参考一下,尝试把点换成图片

2020.12.04改:

var _this = this
            map.on('load', function () {
     
                map.addSource("geojson", _this.createDot([xx,xx], 0.007));
                map.loadImage('/static/img/pen.png', 
                function(error, image) {
     
                    if (error) throw error;
                    map.addImage('point', image);
                    map.addLayer({
     
                        "id": "points",
                        "type": "symbol",
                        "source": "geojson",
                        "layout": {
     
                            "icon-image": "point",
                            "icon-size": 0.1
                        },
                        
                    });
                })
            })
            // 更新位置的方法
            this.updata = function(){
     
                console.log(this.transPosition)
                let data = this.createDot([this.transPosition[0],this.transPosition[1]], 0.007).data
                map.getSource('geojson').setData(data);
            }

        },

        
        // 返回json格式
        createDot(center){
     

            var coords = {
     
                latitude: center[1],
                longitude: center[0]
            };

            var ret = [];
            ret.push([coords.longitude, coords.latitude]);
            ret.push(ret[0]);

            return {
     
                "type": "geojson",
                "data": {
     
                    "type": "FeatureCollection",
                    "features": [{
     
                        "type": "Feature",
                        "geometry": {
     
                            "type": "Point",
                            "coordinates": ret[0]
                        }
                    }]
                }
            };
        }

根据坐标修改点的位置

回到我们熟悉的Cesium,这里有点小问题,用moveStart或者moveEnd其实效果都是不很好,很长一段移动的话,是不会一直显示的,比如你一直直行,就只会更新一下,但是你改变方向或者缩放还是能继续触发的,我暂时也没想到别的办法。(测试好像没有问题)

viewer.scene.camera.moveStart.addEventListener(function(e){
     
              console.log(viewer.camera.position)
              var position = viewer.camera.position
              var arr = []
              var cartographic = Cesium.Cartographic.fromCartesian(position)
              arr.push(Cesium.Math.toDegrees(cartographic.longitude))
              arr.push(Cesium.Math.toDegrees(cartographic.latitude))
              _this.transPosition = arr
            });

2020.12.04改:用changed会好很多。

viewer.scene.camera.changed.addEventListener(function(){
     
              console.log(`changed,${
       viewer.camera.position}`)
              var position = viewer.camera.position
              var arr = []
              var cartographic = Cesium.Cartographic.fromCartesian(position)
              arr.push(Cesium.Math.toDegrees(cartographic.longitude))
              arr.push(Cesium.Math.toDegrees(cartographic.latitude))
              _this.transPosition = arr
            })

改变点的坐标的话,这边有个方法,写在小地图这个组件里面就行了

	let data = this.createDot([this.transPosition[0],this.transPosition[1]], 0.01).data
    map.getSource('polygon').setData(data);

父子组件通信我就不在这里赘述了。

如何监听坐标的改变

最后就是监听了,在watch里面监听,然后调用上面的方法。

watch:{
     
        transPosition(n,o){
     
            if(o!=''){
     
                this.XXX()//调用上面的方法
            }
        }
    }

你可能感兴趣的:(Cesium,webgl,js,vue)