cesium 使用supercluster.js插件实现聚合功能

引入supercluster.js脚本

 <script id="cesium_sandcastle_script">

    function startup(Cesium) {

      'use strict';

      //Sandcastle_Begin

      //设置主视角,默认进入时视角范围

      SetHoumeViewerjd(118.25669445145353, 21.58050898317632, 123.91666536429605, 25.77861604625837);

 //创建cesium地球

      var viewer = new Cesium.Viewer("cesiumContainer", {

        selectionIndicator: true,

        infoBox: true,

        //需要进行可视化的数据源的集合

        animation: true, //是否显示动画控件

        shouldAnimate: true,

        homeButton: true, //是否显示Home按钮

        fullscreenButton: true, //是否显示全屏按钮

        baseLayerPicker: true, //是否显示图层选择控件

        geocoder: false, //是否显示地名查找控件

        timeline: true, //是否显示时间线控件

        sceneModePicker: true, //是否显示投影方式控件

        navigationHelpButton: true, //是否显示帮助信息控件

        requestRenderMode: true, //启用请求渲染模式

        scene3DOnly: false, //每个几何实例将只能以3D渲染以节省GPU内存

        sceneMode: 3, //初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode

        //加载天地图影像地图,WebMapTileServiceImageryProvider该接口是加载WMTS服务的接口

        //tileset添加地形,本地地址

        imageryProvider: new Cesium.TileMapServiceImageryProvider({

          url: 'http://192.168.2.27:8080' + '/TMS/',

          fileExtension: 'jpg',

          layer: 'img',

          style: 'default',

          tileMatrixSetID: 'w',

          format: 'tiles',

          maximumLevel: 20,

          name: "main"

        }),

      });

      //去掉版权信息

      viewer._cesiumWidget._creditContainer.style.display = "none";

      //光照

      viewer.scene.globe.enableLighting = false;

      //地形深度

      viewer.scene.globe.depthTestAgainstTerrain = false;


      var level;//当前地图级别


      //设置相机主视角

      function SetHoumeViewerjd(west, south, east, north) {

        //参数为经纬度

        Cesium.Camera.DEFAULT_VIEW_RECTANGLE = new Cesium.Rectangle.fromDegrees(west, south, east, north);

        if (Cesium.defined(viewer)) {

          var hw1 = viewer.camera.computeViewRectangle();

          console.log("设置后相机视角", hw1);

        }

      }



      //加载poi数据

      function LoadJsonData() {

        getJSON('../Apps/SampleData/geojson/cadshp/上海市-矢量地图_百度POI (V1.0)1.json', (geojson) => {

          console.log("加载数据:", geojson.features);

          //相机移动事件,获取当前地图级别,相机视角范围

          viewer.camera.moveEnd.addEventListener(GetLevel);


          //设置地图当前级别,当前相机视角

          function GetLevel() {

            var tileRender = viewer.scene.globe._surface._tilesToRender;

            if (tileRender && tileRender.length > 0) {

              level = tileRender[0]._level;

              var v3d = GetViewerExtent();

              console.log("当前相机视角:", v3d);


              viewer.entities.removeAll();//清除全部entity

              JuHe(geojson, level, v3d);//聚合算法,技术poi聚合数据

            }

          }

        });

      }


      //聚合算法,json,当前地图级别

      function JuHe(geojson, level, v3d) {

//聚合初始化      

var supercluster = new Supercluster({

          log: true,

          radius: 50,

          extent: 256,

          minZoom: 0,

          maxZoom: 18

        });

       //加载数据

        supercluster.load(geojson.features);


        // var clusters = supercluster.getClusters([

        //    viewer.camera.getExtent()

        // ], viewer.camera.getMagnitude());

        // var clusters = supercluster.getClusters([

        //   -180, -90, 180, 90

        // ], level);

      //获取聚合数据

        var clusters = supercluster.getClusters([

          v3d.xmin, v3d.ymin, v3d.xmax, v3d.ymax

        ], level);


        console.log("所有需要聚合的数据:", clusters);

        //循环生成聚合数据点

        for (var i = 0; i < clusters.length; i++) {

          var cluster = clusters[i];


          if (cluster.properties.cluster) {

            // 聚合点点位

            var clusterEntity = viewer.entities.add({

              position: Cesium.Cartesian3.fromDegrees(cluster.geometry.coordinates[0], cluster.geometry.coordinates[1]),

              billboard: {

                image: '../Apps/public/poi/SH_text_daxinggouwuguangchang.png',

                width: 20,

                height: 26,

                //scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e6, 0.1)

              },

              label: {

                text: String(cluster.properties.point_count),

                font: '14px sans-serif',

                //scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e6, 0.1),

                pixelOffset: new Cesium.Cartesian2(0, -30)

              }

            });

          } else {

            //根据点位类型,渲染不同的图标

            var imageurl;

            // 单个点位

            if (cluster.properties.stdtag == "旅游景点;其他") {

              imageurl = '../Apps/public/poi/SH_text_lvyou.png'

            } else if (cluster.properties.stdtag == "酒店;其他") {

              imageurl = '../Apps/public/poi/SH_text_zhusu.png'

            } else if (cluster.properties.stdtag == "购物;其他") {

              imageurl = '../Apps/public/poi/SH_text_daxinggouwuguangchang.png'

            }

            else if (cluster.properties.stdtag == "生活服务;其他") {

              imageurl = '../Apps/public/poi/SH_text_daxinggouwuguangchang.png'

            } else if (cluster.properties.stdtag == "房地产;其他") {

              imageurl = '../Apps/public/poi/SH_text_daxinggouwuguangchang.png'

            } else if (cluster.properties.stdtag == "文化传媒;其他") {

              imageurl = '../Apps/public/poi/SH_text_juyuangongyuandaxueyizhi.png'

            } else if (cluster.properties.stdtag == "休闲娱乐;其他") {

              imageurl = '../Apps/public/poi/SH_text_juyuangongyuandaxueyizhi.png'

            } else if (cluster.properties.stdtag == "旅游景点;博物馆") {

              imageurl = '../Apps/public/poi/SH_text_juyuangongyuandaxueyizhi.png'

            } else if (cluster.properties.stdtag == "旅游景点;博物馆") {

              imageurl = '../Apps/public/poi/SH_text_juyuangongyuandaxueyizhi.png'

            } else {

              imageurl = '../Apps/public/poi/point.png'

            }


            var markerEntity = viewer.entities.add({

              position: Cesium.Cartesian3.fromDegrees(cluster.geometry.coordinates[0], cluster.geometry.coordinates[1]),

              billboard: {

                image: imageurl,

                width: 20,

                height: 26

              },

              label: {

                text: String(cluster.properties.Name),

                font: '14px sans-serif',

                //scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e6, 0.1),

                pixelOffset: new Cesium.Cartesian2(0, -30)

              }

            });

          }

        }

      }


      // 获取当前三维范围

      function getCurrentExtent() {


        // 范围对象

        var extent = {};


        // 得到当前三维场景

        var scene = viewer.scene;


        // 得到当前三维场景的椭球体

        var ellipsoid = scene.globe.ellipsoid;

        var canvas = scene.canvas;


        // canvas左上角

        var car3_lt = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, 0), ellipsoid);


        // canvas右下角

        var car3_rb = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(canvas.width, canvas.height), ellipsoid);


        // 当canvas左上角和右下角全部在椭球体上

        if (car3_lt && car3_rb) {

          var carto_lt = ellipsoid.cartesianToCartographic(car3_lt);

          var carto_rb = ellipsoid.cartesianToCartographic(car3_rb);

          // extent.xmin = Cesium.Math.toDegrees(carto_lt.longitude);

          // extent.ymax = Cesium.Math.toDegrees(carto_lt.latitude);

          // extent.xmax = Cesium.Math.toDegrees(carto_rb.longitude);

          // extent.ymin = Cesium.Math.toDegrees(carto_rb.latitude);


          extent.xmin = carto_lt.longitude;

          extent.ymax = carto_lt.latitude;

          extent.xmax = carto_rb.longitude;

          extent.ymin = carto_rb.latitude;

        }


        // 当canvas左上角不在但右下角在椭球体上

        else if (!car3_lt && car3_rb) {

          var car3_lt2 = null;

          var yIndex = 0;

          do {

            // 这里每次10像素递加,一是10像素相差不大,二是为了提高程序运行效率

            yIndex <= canvas.height ? yIndex += 10 : canvas.height;

            car3_lt2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, yIndex), ellipsoid);

          } while (!car3_lt2);

          var carto_lt2 = ellipsoid.cartesianToCartographic(car3_lt2);

          var carto_rb2 = ellipsoid.cartesianToCartographic(car3_rb);

          // extent.xmin = Cesium.Math.toDegrees(carto_lt2.longitude);

          // extent.ymax = Cesium.Math.toDegrees(carto_lt2.latitude);

          // extent.xmax = Cesium.Math.toDegrees(carto_rb2.longitude);

          // extent.ymin = Cesium.Math.toDegrees(carto_rb2.latitude);


          extent.xmin = carto_lt.longitude;

          extent.ymax = carto_lt.latitude;

          extent.xmax = carto_rb.longitude;

          extent.ymin = carto_rb.latitude;

        }


        // 获取高度

        extent.height = Math.ceil(viewer.camera.positionCartographic.height);

        return extent;

      }



      //获取相机当前视角

      function GetViewerExtent() {

        // 范围对象

        var extent = {};

        var hw = viewer.camera.computeViewRectangle();

        console.log("当前相机视角", hw);


        var maxx = Cesium.Math.toDegrees(hw.east);

        var maxy = Cesium.Math.toDegrees(hw.north);

        var minx = Cesium.Math.toDegrees(hw.west);

        var miny = Cesium.Math.toDegrees(hw.south);


        console.log("相机经纬度---", maxx, "---", maxy, "---", minx, "---", miny);

        extent.xmin = minx;

        extent.ymax = maxy;

        extent.xmax = maxx;

        extent.ymin = miny;


        return extent;

      }



      $("#load").click(function () {

        console.log("加载");

        LoadJsonData();


      });


      //加载json

      function LoadJson() {

        let index;

        getJSON('../Apps/superclusterdemo/places.json', (geojson) => {

          console.log(`loaded ${geojson.features.length} points JSON `);


          index = new Supercluster({

            log: true,

            radius: 60,

            extent: 256,

            maxZoom: 20

          }).load(geojson.features);

          index.getTile(0, 0, 0);

          console.log("源数据:", index);

          console.log(index.getTile(0, 0, 0));

        });

      }

      //读取json数据POI

      function getJSON(url, callback) {

        const xhr = new XMLHttpRequest();

        xhr.open('GET', url, true);

        xhr.responseType = 'json';

        xhr.setRequestHeader('Accept', 'application/json');

        xhr.onload = function () {

          if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 300 && xhr.response) {

            callback(xhr.response);

          }

        };

        xhr.send();

      }

      //Sandcastle_End

      Sandcastle.finishedLoading();

    }

    if (typeof Cesium !== 'undefined') {

      window.startupCalled = true;

      startup(Cesium);

    }

  </script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值