var CesiumOverviewMapControl = function () { this.init.apply(this, arguments); }; CesiumOverviewMapControl.prototype = { _container: null, _miniMap: null, _viewerMoving: false, _miniMapMoving: false, _userToggledDisplay: false, _minimized: false, _isScreen:false, _oldWidth:'', _oldHeight:'', viewer: null, tileLayer: null, pipeLayerObj:null, pipeLayer:{ url:"", subLayers:null }, options: { position: 'bottomleft', toggleDisplay: true, zoomLevelOffset: -5, zoomLevelFixed: false, centerFixed: false, zoomControl: false, zoomAnimation: false, autoToggleDisplay: false, minimized: false, isScreen:false, width: '150px', height: '150px', collapsedWidth: '19px', collapsedHeight: '19px', 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._isScreen=this.options.isScreen; this._initMap(); this._showInitView(); return this; }, updateAimingRect: function () { var _this = this; var rect = _this._getViewRange(); if(rect) _this._aimingRect.setBounds(rect); }, splitScreen: function (options) {//分屏 this._oldWidth=this.options.width; this._oldHeight=this.options.height; this.options.width=options.width; this.options.height=options.height; this._container.style.width = this.options.width; this._container.style.height = this.options.height; this._miniMap.remove(); $(this._container).empty().removeAttr("style").removeAttr("tabindex").removeClass("leaflet-container").removeClass("leaflet-touch").removeClass("leaflet-fade-anim"); this._miniMap=null; this._isScreen=true; setTimeout(function () { this.viewer.scene.camera.moveEnd._listeners=[]; this.viewer.scene.camera.moveEnd._scopes=[]; this.viewer.scene.camera.moveStart._listeners=[]; this.viewer.scene.camera.moveStart._scopes=[]; this._initMap(); this._showInitView(); }.bind(this), 300); }, restoreScreen:function(){ this.options.width=this._oldWidth; this.options.height=this._oldHeight; this._container.style.width = this.options.width; this._container.style.height = this.options.height; this._miniMap.remove(); $(this._container).empty().removeAttr("style").removeAttr("tabindex").removeClass("leaflet-container").removeClass("leaflet-touch").removeClass("leaflet-fade-anim"); this._miniMap=null; this._isScreen=false; setTimeout(function () { this.viewer.scene.camera.moveEnd._listeners=[]; this.viewer.scene.camera.moveEnd._scopes=[]; this.viewer.scene.camera.moveStart._listeners=[]; this.viewer.scene.camera.moveStart._scopes=[]; this._initMap(); this._showInitView(); }.bind(this), 300); }, _initMap: function () { var _this = this; this._container.style.width = this.options.width; this._container.style.height = this.options.height L.DomEvent.disableClickPropagation(_this._container); L.DomEvent.on(_this._container, 'mousewheel', L.DomEvent.stopPropagation); var mapOptions = { logoControl: false, 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.EPSG4326,//L.CRS.TianDiTu_WGS84, //crs: L.CRS.EPSG3857, center: [0, 0], 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; layer.forEach(function(item,index){ _this._miniMap.addLayer(item); }.bind(_this)) if(this.pipeLayer && this.pipeLayer.subLayers) this.addPipeLayers(this.pipeLayer.url,this.pipeLayer.subLayers); // 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._isScreen==false) { this._addToggleButton(); } _this._miniMap.whenReady(L.Util.bind(function () { var bounds = _this._getViewRange(); if(bounds){ _this._aimingRect = L.rectangle(bounds, _this.options.aimingRectOptions).addTo(_this._miniMap); _this._shadowRect = L.rectangle(bounds, _this.options.shadowRectOptions).addTo(_this._miniMap); if(_this._isScreen==true){ this._aimingRect.setStyle({opacity: 0, fillOpacity: 0}); } var camera = _this.viewer.scene.camera; camera.moveEnd.addEventListener(_this._moveEnd.bind(_this)); camera.moveStart.addEventListener(_this._moveStart.bind(_this)); _this._miniMap.on('movestart', _this._onMiniMapMoveStarted, _this); _this._miniMap.on('move', _this._onMiniMapMoving, _this); _this._miniMap.on('moveend', _this._onMiniMapMoved, _this); if(_this.options.minimized==true && _this._isScreen==false) _this._toggleDisplayButtonClicked(); _this._container.style.visibility='visible'; } }, _this)); return _this._container; }, _moveEnd:function (e) { var _this = this; if(_this._miniMap){ var rect = _this._getViewRange(); if (!_this._miniMapMoving) { _this._viewerMoving = true; if(rect){ var zrect = _this._getZoomOutRange(rect); _this._miniMap.fitBounds(zrect); _this._setDisplay(_this._decideMinimized()); } } else { _this._miniMapMoving = false; } if(rect) _this._aimingRect.setBounds(rect); } }, _moveStart:function (e) { var _this = this; if(_this._miniMap){ var rect = _this._getViewRange(); if(rect) _this._aimingRect.setBounds(rect); } }, _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; this._toggleDisplayButton.style.height = this.options.collapsedHeight; }, _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(); if(rect){ 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; this._container.style.height = this.options.collapsedHeight; this._toggleDisplayButton.className += (' minimized-' + this.options.position); this._toggleDisplayButton.title = this.options.strings.showText; } else { this._container.style.display = 'none'; } this._minimized = true; this.options.minimized=true; this._onToggle(); }, _restore: function () { if (this.options.toggleDisplay) { this._container.style.width = this.options.width; this._container.style.height = this.options.height; 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.options.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(this._isScreen?{opacity: 0, fillOpacity: 0}:{ opacity: 1, fillOpacity: 0.3 }); } } }, _onMiniMapMoved: function (e) { if (!this._viewerMoving&&!this._minimized) { this._miniMapMoving = true; var rect = this._isScreen?this._miniMap.getBounds():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 centerPt=null; centerPt=Cesium.Rectangle.center(destination, centerPt); var viewer = this.viewer; var camera = viewer.scene.camera; var cartographic=Cesium.Cartographic.fromCartesian(camera.position); var longitude = Cesium.Math.toDegrees(cartographic.longitude); var latitude = Cesium.Math.toDegrees(cartographic.latitude); var currentHeight=this.viewer.scene.getHeight(longitude,latitude); destination.height=(cartographic.height-currentHeight)+this.viewer.scene.getHeight(Cesium.Math.toDegrees(centerPt.longitude),Cesium.Math.toDegrees(centerPt.latitude));; var orientation = { heading: Cesium.Math.toRadians(0), pitch:camera.pitch,//Cesium.Math.toRadians(-90), roll:camera.roll//0.0 }; this.viewer.scene.camera.setView({ destination: destination, orientation: orientation }); //获取当前地图范围 /*var bounds = this._miniMap.getBounds();//map.getExtent(); //根据给定的地图范围计算场景的高度 var altitude = _calculateAltitudeFromBounds(bounds); //获取地图中心点 var center = map.getCenter(); //设置场景相机 var camera = new SuperMap.Web.Realspace.Camera(center.lon, center.lat, altitude); camera.set_heading(0); sceneControl.get_scene().set_camera(camera);*/ 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 bounds=null; if(viewer){ var camera = viewer.scene.camera; var range = camera.computeViewRectangle(); if(camera && range){ var west=undefined,east=undefined,north=undefined,south=undefined; if(range.west !=undefined) west = range.west / Math.PI * 180; if(range.east !=undefined) east = range.east / Math.PI * 180; if(range.north !=undefined) north = range.north / Math.PI * 180; if(range.south !=undefined) south = range.south / Math.PI * 180; if(west!=undefined && east!=undefined && north!=undefined && south!=undefined) 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(); if(this._isScreen==false){ 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; }else{ //获取场景相机 var viewer = this.viewer; var camera = viewer.scene.camera; var cartographic=Cesium.Cartographic.fromCartesian(camera.position); //获取场景高度 var altitude =cartographic.height; //获取经度 var longitude = Cesium.Math.toDegrees(cartographic.longitude); //获取纬度 var latitude = Cesium.Math.toDegrees(cartographic.latitude); //根据给定的场景高度计算地图中显示范围的宽度 var size = this._calculateSizeFromAltitude(altitude); size = size * 0.19; west=longitude - size; east=longitude + size; north=latitude + size; south=latitude - size; } 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; }, /// /// 根据给定的场景高度计算地图中显示范围的宽度 /// /// 场景高度 /// 地图显示范围尺寸 _calculateSizeFromAltitude(altitude) { var _PI = 3.1415926; var _earthRadius = 6378137; var size; if (altitude >= _earthRadius) {//当场景高度大于可全幅显示整球的高度时 var ratio = (altitude + _earthRadius) * 0.5; size = 120 * ratio / _earthRadius } else {//当场景高度小于可全幅显示整球的高度时,即无法看到整球时 var tan30 = Math.tan(_PI / 6); //设置方程组的a,b,c var a = (Math.pow(tan30, 2) + 1) * Math.pow(_earthRadius, 2); var b = -2 * (_earthRadius + altitude) * _earthRadius * Math.pow(tan30, 2); var c = Math.pow(tan30, 2) * Math.pow(_earthRadius + altitude, 2) - Math.pow(_earthRadius, 2.0); //解一元二次方程,取锐角,因此余弦值较大 var cosd = (-b + Math.sqrt(Math.pow(b, 2) - 4 * a * c)) / (2 * a); var d = Math.acos(cosd); var widthd = 2 * d * _earthRadius; size = (widthd / (_PI * _earthRadius)) * 180; } return size; }, /// /// 根据给定的地图范围计算场景的高度 /// /// 地图范围 /// 场景高度 _calculateAltitudeFromBounds(bounds) { var _PI = 3.1415926; var _earthRadius = 6378137; var altitude = _earthRadius; //var boundsWidth = bounds.right - bounds.left; var boundsWidth = bounds.getEast() - bounds.getWest(); if (boundsWidth >= 120) { altitude = _earthRadius * boundsWidth / 60 - _earthRadius; } else if (boundsWidth != 0) { var angle1 = (boundsWidth / 360) * _PI; var height = Math.sin(angle1) * _earthRadius; var a = height / Math.tan(angle1); var b = height / Math.tan(_PI / 6); altitude = a + b - _earthRadius; } return altitude; }, addPipeLayers :function (url, subLayers) { this.createTempLayer(url, subLayers); }, getLayerStatusList: function (subLayers) { var parameters = new SuperMap.SetLayerStatusParameters(); for (var i = 0; i < subLayers.length; i++) { var layerStatus = new SuperMap.LayerStatus(); layerStatus.layerName = subLayers[i].name; layerStatus.isVisible = eval(subLayers[i].visible); parameters.layerStatusList.push(layerStatus); } parameters.holdTime=30; return parameters; }, createTempLayer:function (url, subLayers) { var layerStatusParameters = this.getLayerStatusList(subLayers); L.supermap.layerInfoService(url).setLayerStatus(layerStatusParameters, function (createTempLayerEventArgs) { var tempLayerID = createTempLayerEventArgs.result.newResourceID; if(this.pipeLayerObj){ this._miniMap.removeLayer(this.pipeLayerObj); } this.pipeLayerObj=L.supermap.tiledMapLayer(url, { layersID: tempLayerID }); this.pipeLayerObj.addTo(this._miniMap); }.bind(this)); }, CLASS_NAME: "CesiumOverviewMapControl" };