Cesium鹰眼功能

Posted hpugisers

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cesium鹰眼功能相关的知识,希望对你有一定的参考价值。

Cesium鹰眼实现的功能,有两种方式:一种声明两个viewer,另一种就是通过Leaflet。这里我们采用第二种方式,用到一位道友自定义鹰眼插件,这里我们稍微改进一下(ES6方式),下面我们来介绍一下如何实现

一、效果图
二、实现过程
1、插件下载网址https://github.com/leation/OverviewMapForCesium
2、使用环境

  • Cesium
  • Leaflet
  • Vue
  • webpack
    3、安装Leaflet
npm install leaflet --save

3、html声明

<div id="overview" class="leaflet-control-minimap"></div>

4、leaflet引入

import * as L from 'leaflet'

5、css引入

<style>
@import '../css/Control.MiniMap.css';
#overview 
            z-index: 99998;
            width: 150px;
            height: 150px;
            position: absolute;
            right: 10px;
            bottom: 50px;
        
</style>

6、vue中使用

methods:
   initOverview: function (viewer) 
        var url = "http://mt0.google.cn/vt/lyrs=t,r&hl=zh-CN&gl=cn&x=x&y=y&z=z";
        var layer = new L.TileLayer(url, 
            minZoom: 0,
            maxZoom: 20
        );
        var container = document.getElementById("overview");
        var options = 
            container: container,
            toggleDisplay: true,
            width: 150,
            height: 150,
            position: "topright",
            aimingRectOptions: 
                color: "#ff1100",
                weight: 3
            ,
            shadowRectOptions: 
                color: "#0000AA",
                weight: 1,
                opacity: 0,
                fillOpacity: 0
            
        ;       
       var overviewCtr =new CesiumOverviewMapControl(viewer, layer, options);
      
  
  mounted() 
  .........
   this.initOverview(viewer);
  ,

7、CesiumOverviewMapControl改写

import Cesium from 'cesium/Cesium'
var CesiumOverviewMapControl = function () 
  this.init.apply(this, arguments)

CesiumOverviewMapControl.prototype = 
  _container: null,
  _miniMap: null,
  _viewerMoving: false,
  _miniMapMoving: false,
  _userToggledDisplay: false,
  _minimized: false,
  viewer: null,
  tileLayer: null,
  options: 
    position: 'bottomleft',
    toggleDisplay: true,
    zoomLevelOffset: -5,
    zoomLevelFixed: false,
    centerFixed: false,
    zoomControl: false,
    zoomAnimation: false,
    autoToggleDisplay: false,
    minimized: false,
    width: 150,
    height: 150,
    collapsedWidth: 19,
    collapsedHeight: 19,
    aimingRectOptions:  color: '#ff7800', weight: 1, interactive: false ,
    shadowRectOptions:  color: '#000000', weight: 1, interactive: false, opacity: 0, fillOpacity: 0 ,
    strings:  hideText: '隐藏鹰眼', showText: '显示鹰眼' ,
    mapOptions: 
      toggleDisplay: true,
      aimingRectOptions: 
        color: '#ff1100',
        weight: 3
      ,
      shadowRectOptions: 
        color: '#0000AA',
        weight: 1,
        opacity: 0,
        fillOpacity: 0
      
    
  ,
  init: function (viewer, layer, options) 
    this.viewer = viewer
    this.tileLayer = layer
    this._container = options.container
    L.Util.setOptions(this, options)
    this.options.aimingRectOptions.interactive = false
    this.options.shadowRectOptions.interactive = false
    this._initMap()
    this._showInitView()
  ,
  updateAimingRect: function () 
    var _this = this
    var rect = _this._getViewRange()
    _this._aimingRect.setBounds(rect)
  ,
  _initMap: function () 
    var _this = this

    this._container.style.width = this.options.width + 'px'
    this._container.style.height = this.options.height + 'px'

    L.DomEvent.disableClickPropagation(_this._container)
    L.DomEvent.on(_this._container, 'mousewheel', L.DomEvent.stopPropagation)

    var mapOptions = 
      attributionControl: false,
      dragging: !_this.options.centerFixed,
      zoomControl: _this.options.zoomControl,
      zoomAnimation: _this.options.zoomAnimation,
      autoToggleDisplay: _this.options.autoToggleDisplay,
      touchZoom: _this.options.centerFixed ? 'center' : !_this._isZoomLevelFixed(),
      scrollWheelZoom: _this.options.centerFixed ? 'center' : !_this._isZoomLevelFixed(),
      doubleClickZoom: _this.options.centerFixed ? 'center' : !_this._isZoomLevelFixed(),
      boxZoom: !_this._isZoomLevelFixed(),
      crs: L.CRS.EPSG3857,
      center: [30, 120],
      zoom: 1
    
    mapOptions = L.Util.extend(_this.options.mapOptions, mapOptions) // merge
    // with
    // priority
    // of
    // the
    // local
    // mapOptions
    // object.

    _this._miniMap = new L.Map(_this._container, mapOptions)

    var layer = this.tileLayer
    _this._miniMap.addLayer(layer)

    // These bools are used to prevent infinite loops of the two maps
    // notifying each other that they've moved.
    _this._viewerMoving = true
    _this._miniMapMoving = false

    // Keep a record of _this to prevent auto toggling when the user
    // explicitly doesn't want it.
    _this._userToggledDisplay = false
    _this._minimized = false

    if (this.options.toggleDisplay) 
      this._addToggleButton()
    

    _this._miniMap.whenReady(L.Util.bind(function () 
      var bounds = _this._getViewRange()
      _this._aimingRect = L.rectangle(bounds, _this.options.aimingRectOptions).addTo(_this._miniMap)
      _this._shadowRect = L.rectangle(bounds, _this.options.shadowRectOptions).addTo(_this._miniMap)

      var camera = _this.viewer.scene.camera
      camera.moveEnd.addEventListener(function (e) 
        var rect = _this._getViewRange()
        if (!_this._miniMapMoving) 
          _this._viewerMoving = true
          var zrect = _this._getZoomOutRange(rect)
          _this._miniMap.fitBounds(zrect)
          _this._setDisplay(_this._decideMinimized())
         else 
          _this._miniMapMoving = false
        
        _this._aimingRect.setBounds(rect)
      )
      camera.moveStart.addEventListener(function (e) 
        var rect = _this._getViewRange()
        _this._aimingRect.setBounds(rect)
      )

      _this._miniMap.on('movestart', _this._onMiniMapMoveStarted, _this)
      _this._miniMap.on('move', _this._onMiniMapMoving, _this)
      _this._miniMap.on('moveend', _this._onMiniMapMoved, _this)
    , _this))

    return _this._container
  ,
  _addToggleButton: function () 
    this._toggleDisplayButton = this.options.toggleDisplay ? this._createButton(
      '', this._toggleButtonInitialTitleText(), ('leaflet-control-minimap-toggle-display leaflet-control-minimap-toggle-display-' +
                this.options.position), this._container, this._toggleDisplayButtonClicked, this) : undefined
    // this._toggleDisplayButton.style.zIndex = 99999;
    this._toggleDisplayButton.style.width = this.options.collapsedWidth + 'px'
    this._toggleDisplayButton.style.height = this.options.collapsedHeight + 'px'
  ,

  _toggleButtonInitialTitleText: function () 
    if (this.options.minimized) 
      return this.options.strings.showText
     else 
      return this.options.strings.hideText
    
  ,

  _createButton: function (html, title, className, container, fn, context) 
    var link = L.DomUtil.create('a', className, container)
    link.innerHTML = html
    link.href = '#'
    link.title = title

    var stop = L.DomEvent.stopPropagation

    L.DomEvent
      .on(link, 'click', stop)
      .on(link, 'mousedown', stop)
      .on(link, 'dblclick', stop)
      .on(link, 'click', L.DomEvent.preventDefault)
      .on(link, 'click', fn, context)

    return link
  ,

  _toggleDisplayButtonClicked: function () 
    this._userToggledDisplay = true
    if (!this._minimized) 
      this._minimize()
     else 
      this._restore()
    
  ,
  _showInitView: function () 
    var rect = this._getViewRange()
    var zrect = this._getZoomOutRange(rect)
    this._miniMap.fitBounds(zrect)
  ,
  _setDisplay: function (minimize) 
    if (minimize !== this._minimized) 
      if (!this._minimized) 
        this._minimize()
       else 
        this._restore()
      
    
  ,
  _minimize: function () 
    // hide the minimap
    if (this.options.toggleDisplay) 
      this._container.style.width = this.options.collapsedWidth + 'px'
      this._container.style.height = this.options.collapsedHeight + 'px'
      this._toggleDisplayButton.className += (' minimized-' + this.options.position)
      this._toggleDisplayButton.title = this.options.strings.showText
     else 
      this._container.style.display = 'none'
    
    this._minimized = true
    this._onToggle()
  ,
  _restore: function () 
    if (this.options.toggleDisplay) 
      this._container.style.width = this.options.width + 'px'
      this._container.style.height = this.options.height + 'px'
      this._toggleDisplayButton.className = this._toggleDisplayButton.className
        .replace('minimized-' + this.options.position, '')
      this._toggleDisplayButton.title = this.options.strings.hideText
     else 
      this._container.style.display = 'block'
    
    this._minimized = false
    this._onToggle()
  ,
  _onMiniMapMoveStarted: function (e) 
    if (!this.options.centerFixed) 
      var lastAimingRect = this._aimingRect.getBounds()
      var sw = this._miniMap.latLngToContainerPoint(lastAimingRect.getSouthWest())
      var ne = this._miniMap.latLngToContainerPoint(lastAimingRect.getNorthEast())
      this._lastAimingRectPosition =  sw: sw, ne: ne 
    
  ,
  _onMiniMapMoving: function (e) 
    if (!this.options.centerFixed) 
      if (!this._viewerMoving && this._lastAimingRectPosition) 
        this._shadowRect.setBounds(new L.LatLngBounds(this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.sw), this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.ne)))
        this._shadowRect.setStyle( opacity: 1, fillOpacity: 0.3 )
      
    
  ,
  _onMiniMapMoved: function (e) 
    if (!this._viewerMoving) 
      this._miniMapMoving = true

      var rect = this._shadowRect.getBounds()
      var west = rect.getWest()
      var east = rect.getEast()
      var north = rect.getNorth()
      var south = rect.getSouth()
      var destination = Cesium.Rectangle.fromDegrees(west, south, east, north)
      var orientation = 
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-90),
        roll: 0.0
      
      this.viewer.scene.camera.setView(
        destination: destination,
        orientation: orientation
      )
      this._shadowRect.setStyle( opacity: 0, fillOpacity: 0 )
     else 
      this._viewerMoving = false
    
  ,
  _isZoomLevelFixed: function () 
    var zoomLevelFixed = this.options.zoomLevelFixed
    return this._isDefined(zoomLevelFixed) && this._isInteger(zoomLevelFixed)
  ,
  _decideMinimized: function () 
    if (this._userToggledDisplay) 
      return this._minimized
    

    if (this.options.autoToggleDisplay) 
      var bounds = this._getViewRange()
      if (bounds.contains(this._miniMap.getBounds())) 
        return true
      
      return false
    

    return this._minimized
  ,
  _isInteger: function (value) 
    return typeof value === 'number'
  ,
  _isDefined: function (value) 
    return typeof value !== 'undefined'
  ,
  _onToggle: function () 
    L.Util.requestAnimFrame(function () 
      L.DomEvent.on(this._container, 'transitionend', this._fireToggleEvents, this)
      if (!L.Browser.any3d) 
        L.Util.requestAnimFrame(this._fireToggleEvents, this)
      
    , this)
  ,
  _fireToggleEvents: function () 
    L.DomEvent.off(this._container, 'transitionend', this._fireToggleEvents, this)
  ,
  _getViewRange: function () 
    var viewer = this.viewer
    var camera = viewer.scene.camera
    var range = camera.computeViewRectangle()
    var west = range.west / Math.PI * 180
    var east = range.east / Math.PI * 180
    var north = range.north / Math.PI * 180
    var south = range.south / Math.PI * 180
    var bounds = new L.LatLngBounds(
      new L.LatLng(north, west),
      new L.LatLng(south, east)
    )
    return bounds
  ,
  _getZoomOutRange: function (rect) 
    var west = rect.getWest()
    var east = rect.getEast()
    var north = rect.getNorth()
    var south = rect.getSouth()
    var factor = 3.0
    var xdis = Math.abs(east - west)
    var ydis = Math.abs(north - south)
    var xoff = xdis * (factor - 1) / 2.0
    var yoff = ydis * (factor - 1) / 2.0
    west -= xoff
    east += xoff
    north += yoff
    south -= yoff
    if (west < -180) 
      west = -180
    
    if (east > 180) 
      east = 180
    
    if (north > 90) 
      north = 90
    
    if (south < -90) 
      south = -90
    
    var bounds = new L.LatLngBounds(
      new L.LatLng(north, west),
      new L.LatLng(south, east)
    )
    return bounds
  

export default CesiumOverviewMapControl

以上是关于Cesium鹰眼功能的主要内容,如果未能解决你的问题,请参考以下文章

Android 使用百度鹰眼实现运动轨迹功能

ArcGIS Engine开发之鹰眼视图

Android 百度鹰眼轨迹SDK(v2.1.6)

Android 百度鹰眼轨迹SDK(v2.1.6)

《ArcGIS Engine+C#实例开发教程》第五讲 鹰眼的实现

天津政府应急系统之GIS一张图(arcgis api for flex)解说鹰眼模块