123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- import DomUtil from './common/doms.js'
- import '../Assets/styles/StatusBar.css';
- /**
- * 状态栏
- */
- class StatusBar {
- /**
- * 状态栏工具类
- * @param {Viewer} viewer - 三维场景
- */
- constructor(viewer) {
- if (!viewer) throw new Error('viewer is required!');
- this._viewer = viewer;
- this._show = false; //初始化显示状态
- this._handler;
- this._posX;
- this._posY;
- this._posZ;
- this._cameraHeight;
- this._pitch;
- this._heading;
- this._scale;
- this.initListener()
- }
- /**
- * 状态栏参数
- * @readonly
- */
- get params() {
- return {
- posX: this._posX, //经度
- posY: this._posY, //维度
- posZ: this._posZ, //模型高度
- cameraHeight: this._cameraHeight, //相机视角高度
- pitch: this._pitch, //俯仰角
- heading: this._heading, //方向
- scale: this._scale //比例尺
- }
- }
- get statusDom() {
- let innerHtml = `
- <span class="status-scale">
- 比例尺:
- <span class="scale-border">
- ${this._scale}
- </span>
- </span>
- <span class="status-position">
- <span id="status_spaceInfo">空间信息</span>
- 刷帧率:<span id="status_ms"></span>|<span id="status_fps"></span>
- </span>
- `
- return innerHtml
- }
- /**
- * 控制显示Boolean常量
- * @constant
- */
- get show() {
- return this._show
- }
- set show(bool) {
- bool ? this.createStatusBar() : this.removeStatusBar()
- this._show = bool
- }
- initListener() {
- const $this = this
- const scene = this._viewer.scene
- this._scaleListener = function() {
- let width = scene.canvas.clientWidth
- let height = scene.canvas.clientHeight
- let left = scene.camera.getPickRay(
- new Cesium.Cartesian2((width / 2) | 0, height - 1)
- )
- let right = scene.camera.getPickRay(
- new Cesium.Cartesian2((1 + width / 2) | 0, height - 1)
- )
- let globe = scene.globe
- let leftPosition = globe.pick(left, scene)
- let rightPosition = globe.pick(right, scene)
- if (leftPosition && rightPosition) {
- let geodesic = new Cesium.EllipsoidGeodesic()
- let leftCartographic = globe.ellipsoid.cartesianToCartographic(leftPosition)
- let rightCartographic = globe.ellipsoid.cartesianToCartographic(rightPosition)
- geodesic.setEndPoints(leftCartographic, rightCartographic)
- let distance = geodesic.surfaceDistance
- let curScaleNum = $this.closest(distance / 10)
- if (curScaleNum < 1) {
- $this._scale = curScaleNum * 1000 + 'm'
- } else {
- $this._scale = curScaleNum + 'km'
- }
- }
- document.getElementsByClassName("scale-border")[0].innerText = $this._scale;
- if (document.getElementsByClassName("cesium-performanceDisplay-ms").length > 0) {
- document.getElementById("status_ms").innerText = document.getElementsByClassName("cesium-performanceDisplay-ms")[0].innerText;
- }
- if (document.getElementsByClassName("cesium-performanceDisplay-fps").length > 0) {
- document.getElementById("status_fps").innerText = document.getElementsByClassName("cesium-performanceDisplay-fps")[0].innerText;
- }
- }
- }
- createStatusBar() {
- const _delegate = this._viewer
- this.initHandler(_delegate)
- this.initScale(_delegate, true)
- this._domContainer = DomUtil.create(
- 'div',
- 'lk-status-bar',
- document.getElementById(this._viewer._container.id)
- )
- this._domContainer.innerHTML = this.statusDom;
- // var canvas = this._viewer.canvas; // 获取画布
- // this._domContainer.style.width = canvas.width + "px";
- // console.log('画布', canvas.width)
- }
- removeStatusBar() {
- this.initScale(this._viewer, false)
- if (this._handler) {
- this._handler.destroy()
- }
- if (this._domContainer) {
- DomUtil.remove(this._domContainer)
- }
- }
- initHandler(viewer) {
- const $this = this
- this._handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
- const mouseOverHandler = function(movement) {
- /* 识别屏幕位置 */
- let loc = $this._getScreenClickPositionAndHeight(movement.endPosition);
- if (!Cesium.defined(loc)) return;
- if (!loc.lng) return;
- $this._posX = loc.lng.toFixed(8);
- $this._posY = loc.lat.toFixed(8);
- $this._posZ = loc.height.toFixed(2);
- // const cameraH = viewer.camera.positionCartographic.height
- // $this._cameraHeight =
- // cameraH < 1000 ?
- // cameraH.toFixed(2) + 'm' :
- // (cameraH / 1000).toFixed(2) + 'km';
- // $this._pitch = Number(viewer.scene.camera.pitch).toFixed(2);
- // $this._heading = Number(viewer.scene.camera.heading).toFixed(2);
- document.getElementById("status_spaceInfo").innerHTML = `
- <span>经度:${$this._posX}</span>
- <span>纬度:${$this._posY}</span>
- <span>高度:${$this._posZ}</span>
- `;
- }
- this._handler.setInputAction(
- mouseOverHandler,
- Cesium.ScreenSpaceEventType.MOUSE_MOVE
- )
- }
- initScale(viewer, bool) {
- const scene = viewer.scene
- bool
- ?
- scene.postRender.addEventListener(this._scaleListener) :
- scene.postRender.removeEventListener(this._scaleListener)
- }
- closest(num) {
- const scaleList = [
- 0.001,
- 0.002,
- 0.003,
- 0.005,
- 0.01,
- 0.015,
- 0.02,
- 0.025,
- 0.03,
- 0.035,
- 0.04,
- 0.045,
- 0.05,
- 0.06,
- 0.07,
- 0.08,
- 0.09,
- 0.1,
- 0.12,
- 0.15,
- 0.2,
- 0.25,
- 0.3,
- 0.5,
- 1,
- 2,
- 3,
- 5,
- 10,
- 15,
- 20,
- 25,
- 30,
- 35,
- 40,
- 45,
- 50,
- 60,
- 70,
- 80,
- 90,
- 100,
- 120,
- 150,
- 200,
- 250,
- 300,
- 500,
- 1000,
- 2000,
- 5000,
- 10000,
- 100000,
- 500000,
- 1000000
- ]
- let ret = scaleList[0]
- let distance = Math.abs(ret - num)
- for (let i = 1; i < scaleList.length; i++) {
- let newDistance = Math.abs(scaleList[i] - num)
- if (newDistance < distance) {
- distance = newDistance
- ret = scaleList[i]
- }
- }
- return ret
- }
- /**
- * 根据地形或实景或模型检测当前屏幕位置的经纬度及高度
- * @ignore 生成方法时不对外公开
- * @param {JSON} screenPoint 屏幕坐标
- * @param {Number} screenPoint.x 屏幕坐标x
- * @param {Number} screenPoint.y 屏幕坐标y
- * @return {JSON} 位置信息{lng,lat,height}
- */
- _getScreenClickPositionAndHeight(screenPoint) {
- var lng = undefined,
- lat = undefined,
- height = undefined;
- /* 从相机位置到 windowPosition 处的像素创建射线在世界坐标系中 */
- var ray = this._viewer.scene.camera.getPickRay(screenPoint);
- /* 找到射线与渲染的地球表面之间的交点 */
- var position = this._viewer.scene.globe.pick(ray, this._viewer.scene);
- if (position) {
- /* 获取地理位置的制图表达 */
- var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);
- cartographic = Cesium.Cartographic.fromCartesian(position);
- /* 查询屏幕位置的要素 */
- var feature = this._viewer.scene.pick(screenPoint);
- if (feature === undefined && Cesium.defined(cartographic)) {
- lng = this._arcToDegree(cartographic.longitude);
- lat = this._arcToDegree(cartographic.latitude);
- height = cartographic.height;
- } else {
- var cartesian = this._viewer.scene.pickPosition(screenPoint);
- if (Cesium.defined(cartesian)) {
- var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
- if (Cesium.defined(cartographic)) {
- lng = this._arcToDegree(cartographic.longitude);
- lat = this._arcToDegree(cartographic.latitude);
- height = cartographic.height;
- }
- }
- }
- }
- /* 返回结果 */
- return {
- lng: lng,
- lat: lat,
- height: height,
- }
- }
- /**
- * 弧度转度
- * @ignore 生成方法时不对外公开
- * @param {Number} arc 弧度
- * @return {Number} 角度
- */
- _arcToDegree(arc) {
- return arc / Math.PI * 180;
- }
- }
- export default StatusBar
|