Cesium加载图层并获取要素信息的几种方法

        公司项目中需要加载图层获取要素信息,折腾了好久,做个备份吧,如有不对,请批评指正!

        在探索过程中,一共找到了四种方法,下面一一叙述。(个人觉得第四种最好)

一、加载WMS图层,并获取要素信息(很容易但是效率低)

        这主要是使用Cesium加载wms服务,并使用Cesium的pickImageryLayerFeature函数获取要素信息,代码十分简单,但是加载wms的效率比wmts效率低

      var wmsImageryProvider = new Cesium.WebMapServiceImageryProvider({
        url:"",//服务地址,到wmsserver
        layers: "000",//图层名
        rectangle:Cesium.Rectangle.fromDegrees(118.08795779022113,39.55685670605424,118.22210080995278,39.63972903104975),//服务的经纬度区间
        parameters:{
          transparent: false,
          format: "image/jpeg",
          srs: "EPSG:4326",
          //style: "",
        },
        getFeatureInfoParameters:{
          request: "GetFeatureInfo"
        }
      })
      let layer = viewer.imageryLayers.addImageryProvider(wmsImageryProvider);
      var hander = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
      hander.setInputAction(async function (event) {
          viewer.selectedEntity = undefined;
          var pickRay = viewer.camera.getPickRay(event.position);
          var featurePromise = await  viewer.imageryLayers.pickImageryLayerFeatures(pickRay,viewer.scene);
      },Cesium.ScreenSpaceEventType.LEFT_CLICK);

二、加载wms和wmts两个图层(比较鸡肋比较智障的想法)

        既然wms效率低,wmts效率高,那就想着干脆加两个,wms给应隐藏了(当时wmts获取不了属性,我又不知道怎么用js从wms获取要素信息)。

        那么直接将透明度设为0,测试发现将图层layer的show改变是不起作用的

      layer.alpha = 0;

三、加载wmts图层,采用wfs获取要素信息

        需要查看服务内经纬度对应哪一个字段

    test2(){
      var wfsurl = '.../MapServer/WFSServer'//服务地址
      var param = {
        service: 'WFS',
        version: '1.0.0',
        request: 'GetFeature',
        typeName:'',//图层名

      }
      var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
      var ellipsoid = viewer.scene.globe.ellipsoid;
      var th = this
      handler.setInputAction(function (movement) {
          var cartesian = viewer.camera.pickEllipsoid(movement.position,ellipsoid);
          if(cartesian){
            var cartographic = ellipsoid.cartesianToCartographic(cartesian);
            var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
            var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
            var point = longitudeString+','+latitudeString;
            th.queryWFSByPoint(wfsurl,point,param.typeName);
          }
      },Cesium.ScreenSpaceEventType.LEFT_CLICK)
    },
    queryWFSByPoint(wfsurl,point,typeName){
      var filter = '<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">';
      filter += '<Intersects>';
      filter += '<PropertyName>the_geom</PropertyName>';
      filter += '<gml:Point>';
      filter += '<gml:coordinates>' + point + '</gml:coordinates>';
      filter += '</gml:Point>';
      filter += '</Intersects>';
      filter += '</Filter>';
      var param = {
        service: 'WFS',
        version: '1.0.0',
        request: 'GetFeature',
        typeName: typeName,
        filter: filter,
      }
      axios({
        url: wfsurl+this.getParamString(param,wfsurl),
        async: true,
        type: 'GET',
        
      })

    },
    getParamString(obj,existingUrl,uppercase){
       var params = [];
      for(var i in obj){
        params.push(encodeURIComponent(uppercase?i.toUpperCase():i)+'='+encodeURIComponent(obj[i]));
      }
      return ((!existingUrl||existingUrl.indexOf('?')===-1)?'?':'&')+params.join('&');
    },

四、加载wmts采用wms获取要素信息

        加载wmts的方法就不在这说了,可以看我之前的博客,这里只说要素 信息,比较坑的是,这是在你点击的位置的经纬度附近,设置一个偏移量,在这里我设置的0.0003,这个值可以根据自己项目,进行调试,选择一个合适的值,那么经度-0.0003,经度+0.0003,纬度也是,这样构成了一个矩形,width、height、x、y分别是假如这个矩形的像素是width宽,height高,那么点击位置距离矩形左上角的像素距离x、y。这样做的目的是为了适应不同的坐标系。(但属实在这折腾了一两天),在这里因为我上下左右偏移的量是一样的,经过几次求取,发现我的xy都是128,所有就直接写了

    test3(){
      var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
      var ellipsoid = viewer.scene.globe.ellipsoid;
      var th = this
      handler.setInputAction(function (movement) {
        var cartesian = viewer.camera.pickEllipsoid(movement.position,ellipsoid);
        if(cartesian){
          var cartographic = ellipsoid.cartesianToCartographic(cartesian);
          var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
          var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
          //通过经纬度画一个矩形,x,y为以矩形左上角为原点,点击位置的屏幕坐标,通过计算发现,采用wgs84坐标系,width256,height256,点击点往往在中心128,128
/*          var change = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, new Cesium.Cartesian3((longitudeString-0.0003),(latitudeString+0.0003),0));
          var changex = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, new Cesium.Cartesian3(longitudeString,latitudeString,0));
          var changep = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, new Cesium.Cartesian3((longitudeString+0.0003),(latitudeString-0.0003),0));
          var X = (change.x-changex.x)*256/(change.x-changep.x)
          var Y = (change.y-changex.y)*256/(change.y-changep.y)
          console.log(change,movement.position,changex,changep,X,Y)*/
          var wfsurl = '.../MapServer/WMSServer?request=GetFeatureInfo&service=WMS&version=1.1.1'
          var bbox = "&bbox=" + (longitudeString-0.0003) +"%2C"+(latitudeString-0.0003)+"%2C"+(longitudeString+0.0003)+"%2C"+(latitudeString+0.0003);
          var end = "&x=128&y=128&width=256&height=256&srs=EPSG%3A4326&query_layers=000&info_format=application%2Fjson";
          th.test4(wfsurl+bbox+end)

        }
      },Cesium.ScreenSpaceEventType.LEFT_CLICK)
    },
    async test4(url){
      var result = await axios({
        url: url,
        method: 'get',

      })
      var x2js = new X2JS();
      var jsonObj = x2js.xml_str2json(result.data);
      console.log(jsonObj)

    },

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值