Cesium-Leaflet鹰眼图

一、原理

实现鹰眼图的主要搭配方法是Cesium原生、Cesium-Leaflet、Cesium-OpenLayer三种方法。

本文以Cesium作为三维地球框架,以Leaflet作为二维地图框架,来实现鹰眼图的效果。

二、代码

分别引入Cesium和Leaflet的JS和CSS。


    $(function () {
      initWork();
    })

    function initWork () {
      overMap.init(viewer);
    }
    var overMap = {
      init: function (viewer) {
        this.viewer = viewer,
          this.mapEle = window.document.createElement("div"),
          this.mapEle.setAttribute("id", "map2d"),
          this.mapEle.style.height = "250px",
          this.mapEle.style.width = "300px",
          this.mapEle.style.position = "absolute",
          this.mapEle.style.bottom = "30px",
          this.mapEle.style.right = "10px",
          document.body.appendChild(this.mapEle),
          this.showStyle = {
            color: "#ff7800", weight: 1, fill: !0, stroke: !0, opacity: 1
          },
          this.hideStyle = { fill: !1, opacity: 0 },
          this.map = L.map('map2d', {
            center: [31.827107, 117.240601],
            zoom: 13,
            zoomControl: false,
            attributionControl: false
          })
        var mapUrl = "http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}";
        L.tileLayer(mapUrl, {
          maxZoom: 18,
          tileSize: 256,
        }).addTo(this.map),
          // L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
          // }).addTo(this.map),
          this.viewer.scene.postRender.addEventListener(
            this.sceneRenderHandler, this);
      },
      sceneRenderHandler: function (e) {
        var ext = getExtent(this.viewer),
          i = L.latLng(ext.ymin, ext.xmin),
          s = L.latLng(ext.ymax, ext.xmax),
          bounds = L.latLngBounds(i, s);
        if (this.rectangle ? this.rectangle.setBounds(bounds) : this.rectangle = L.rectangle(bounds, this.showStyle).addTo(this.map), -180 == ext.xmin && 180 == ext.xmax && 90 == ext.ymax && -90 == ext.ymin) {
          var center = getCenter(this.viewer);
          this.map.setView([center.y, center.x], 0),
            this.rectangle.setStyle(this.hideStyle)
        }
        else {
          var oBounds = bounds.pad(.5);
          this.map.fitBounds(oBounds),
            this.rectangle.setStyle(this.showStyle)
        }
      },
      hide: function () {
        this.mapEle && (this.mapEle.style.display = "none")
      },
      show: function () {
        this.map && this.mapEle && (this.mapEle.style.display = "block")
      },
      setStyle: function (e) {
        e && (this.showStyle = e)
      },
      destroy: function () {
        this.mapEle && document.getElementsByTagName("body").removeChild(this.mapEle), this.viewer.scene.postRender.removeEventListener(this.sceneRenderHandler, this)
      }
    }
    function getExtent (viewer) {
      var rectangle = viewer.camera.computeViewRectangle(),
        result = getMinMax(rectangle);
      if (result.xmax < result.xmin) {
        var s = result.xmax;
        result.xmax = result.xmin,
          result.xmin = s
      }
      if (result.ymax < result.ymin) {
        var s = result.ymax;
        result.ymax = result.ymin,
          result.ymin = s
      }
      return result
    }
    function getMinMax (rectangle) {
      var t = Number(Cesium.Math.toDegrees(rectangle.west)).toFixed(6),
        i = Number(Cesium.Math.toDegrees(rectangle.east)).toFixed(6),
        n = Number(Cesium.Math.toDegrees(rectangle.north)).toFixed(6);
      return {
        xmin: t,
        xmax: i,
        ymin: Number(Cesium.Math.toDegrees(rectangle.south)).toFixed(6),
        ymax: n
      }
    }
    function getCenter (viewer) {
      var scene = viewer.scene,
        pos = getPos(scene),
        position = pos;
      if (!position) {
        var globe = scene.globe,
          cartographic = scene.camera.positionCartographic.clone(),
          height = globe.getHeight(cartographic);
        cartographic.height = height || 0,
          cartesian = Cesium.Ellipsoid.WGS84.cartographicToCartesian(cartographic)
      }
      var result = toCartographic(position);
      var d = Cesium.Cartesian3.distance(position, viewer.scene.camera.positionWC);
      return result.cameraZ = d,
        result
    }
    function getPos (scene) {
      var canvas = scene.canvas,
        center = new Cesium.Cartesian2(canvas.clientWidth / 2, canvas.clientHeight / 2),
        ray = scene.camera.getPickRay(center);
      return scene.globe.pick(ray, scene) || scene.camera.pickEllipsoid(center)
    }
    function toCartographic (cartesian) {
      var cartographic = Cesium.Cartographic.fromCartesian(cartesian),
        result = {};
      return result.y = Number(Cesium.Math.toDegrees(cartographic.latitude)).toFixed(6),
        result.x = Number(Cesium.Math.toDegrees(cartographic.longitude)).toFixed(6),
        result.z = Number(cartographic.height).toFixed(2),
        result
    }

三、效果图

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值