美文网首页js css htmlweb前端
cesium鼠标滚轮实现geojson的动态加载

cesium鼠标滚轮实现geojson的动态加载

作者: 姜治宇 | 来源:发表于2022-12-27 15:24 被阅读0次

    有这样一个需求:

    当鼠标滚轮向下滚动时,动态加载geojson数据,而向上滚动时,数据自动恢复原样。 1.gif
    首先需要加载出全国的geojson数据,当选择某个省的时候,拾取到这个省的行政码信息,然后请求加载这个省的geojson数据。

    我们可以用MOUSE_MOVE事件,获取鼠标移动时的坐标,从而拾取到这个物体,然后在鼠标滚轮WHEEL事件中,通过上下方向以及层级的判断来触发加载数据。

    async addGeoJsonData(code) {//获取接口数据
          let data = await getGeojsonApi({ admincode: code })
          ...
    },
    setAction() {
                const Cesium = this.Cesium
                //球交互事件
                this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
    
                let leftclick = Cesium.ScreenSpaceEventType.MOUSE_MOVE
                this.viewer.screenSpaceEventHandler.removeInputAction(leftclick)
                this.handler.setInputAction((e) => {
                    // let pickObj = this.viewer.scene.pick(e.position)
                    // console.log(pickObj, e.position)
                    let pickObj = this.viewer.scene.pick(e.endPosition)
                    // 视角飞入
                    if (pickObj && pickObj.id) {
    
                        this.pickObj = pickObj;
                    }
                }, leftclick);
                let wheel = Cesium.ScreenSpaceEventType.WHEEL;
                this.handler.setInputAction((wheel) => {
                    // let pickObj = this.viewer.scene.pick(e.position)
                    console.log('wheeel>>>',wheel);
                    let tiles = new Set();
                    let tilesToRender = this.viewer.scene.globe._surface._tilesToRender;
                    if(Cesium.defined(tilesToRender)){
                        for(let i=0;i<tilesToRender.length;i++){
                            
                            tiles.add(tilesToRender[i].level);
                        }
                        // console.log('当前地图瓦片级别为',tiles);
                        // console.log(Math.max(...tiles));
                        let level = Math.max(...tiles);
                        console.log('level',level);
                        if(wheel > 0) {//当放低镜头时
                        console.log('放低镜头');
                            if(this.pickObj) {
                                let pickObj = this.pickObj;
                                if(level > 3) {
                                    //查询geojson
                                    this.addGeoJsonData(`${pickObj.id.admincode}`)
                                    
                                } 
                            }
    
    
    
                        } else {
                            console.log('拉高镜头');
                            if(level < 5) { //只有当拉高镜头时,清除数据
    
                                this.code = '';
                                this.hideGeoJsonData();
                                this.showGeoJsonData('100000_full');
                                Object.keys(this.labelCont).map(item=>this.labelCont[item].show = true);
    
                            }
                        }
                        
    
                    }
                },wheel);
    
            },
    

    但这样做有个问题,就是会频繁触发addGeoJsonData函数,从而导致数据重复叠加。我希望一个admincode行政区的数据仅加载一次。
    我们可以利用watch来解决这个问题。

    data() {
      return {
        code: ''
      }
    },
    watch: {
            code: {
                handler(val, oldVal) {
                    
                    if(val !== oldVal) {
                        
                        this.addGeoJsonData(val);
                        
                    }
                },
                deep: true,
                immediate: true
            },
    },
    methods: {
        async addGeoJsonData(code) {//获取接口数据
              let data = await getGeojsonApi({ admincode: code })
              ...
        },
        setAction() {
                const Cesium = this.Cesium
                //球交互事件
                this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
    
                let leftclick = Cesium.ScreenSpaceEventType.MOUSE_MOVE
                this.viewer.screenSpaceEventHandler.removeInputAction(leftclick)
                this.handler.setInputAction((e) => {
                    // let pickObj = this.viewer.scene.pick(e.position)
                    // console.log(pickObj, e.position)
                    let pickObj = this.viewer.scene.pick(e.endPosition)
                    // 视角飞入
                    if (pickObj && pickObj.id) {
    
                        this.pickObj = pickObj;
                    }
                }, leftclick);
                let wheel = Cesium.ScreenSpaceEventType.WHEEL;
                this.handler.setInputAction((wheel) => {
                    // let pickObj = this.viewer.scene.pick(e.position)
                    console.log('wheeel>>>',wheel);
                    let tiles = new Set();
                    let tilesToRender = this.viewer.scene.globe._surface._tilesToRender;
                    if(Cesium.defined(tilesToRender)){
                        for(let i=0;i<tilesToRender.length;i++){
                            
                            tiles.add(tilesToRender[i].level);
                        }
                        // console.log('当前地图瓦片级别为',tiles);
                        // console.log(Math.max(...tiles));
                        let level = Math.max(...tiles);
                        console.log('level',level);
                        if(wheel > 0) {//当放低镜头时
                        console.log('放低镜头');
                            if(this.pickObj) {
                                let pickObj = this.pickObj;
                                if(level > 3) {
                                    //查询geojson
                                    this.code = pickObj.id.admincode;
                                    
                                } 
                            }
    
    
    
                        } else {
                            console.log('拉高镜头');
                            if(level < 5) { //只有当拉高镜头时,清除数据
    
                                this.code = '';
                                this.hideGeoJsonData();
                                this.showGeoJsonData('100000_full');
                                Object.keys(this.labelCont).map(item=>this.labelCont[item].show = true);
    
                            }
                        }
                        
    
                    }
                },wheel);
    
            },
    }
    
    
    

    相关文章

      网友评论

        本文标题:cesium鼠标滚轮实现geojson的动态加载

        本文链接:https://www.haomeiwen.com/subject/ytgoqdtx.html