import React, { useEffect, useState, useRef } from 'react' import { Input, Button, Modal, message } from 'antd' import { gcj_decrypt, exetent2AmapPoint, lngLat2WebMercator } from '@/utils/transformUtil' import { GetAllConfig, GetMetaData } from '@/services/gis/gis' import { PdRender, Cesium, } from '@wisdom-cesium/cesium' const { Search } = Input; let pdViewer, viewer, extent, orientation, position; const MapScope = props => { const { visible, confirmModal,item , baseMapData, baseMap, handleType} = props; const [options, setOptions] = useState([]) let el = useRef(null); const [loading, setLoading] = useState(false); let buttonEl = useRef(null); const getBaseMap = () => { if(handleType == 'update') { return item.baseMap.map(item => ({ type : item.baseMap.type, status : item.status })) } else if(handleType == 'add') { if(!baseMapData) return [] let data = baseMapData.map(item => { let map = baseMap.find(({type}) => type === item.type) return { type : map.type, status : item.status || 'notActive' } }) return data } } const getCamera = () => { if (handleType == 'update') { let {mapSettings} = item return mapSettings.camera || {} } else if (handleType == 'add') { return {} } } useEffect(() => { if (visible) { pdViewer = new PdRender({ el: el.current, baseMaps : getBaseMap() || [] , cameraSetting : getCamera () || {} }); viewer = pdViewer.viewer; } }, [visible]); function getOrientation() { const { heading, pitch, roll } = viewer.camera; const headingDegrees = Cesium.Math.toDegrees(heading); const pitchDegrees = Cesium.Math.toDegrees(pitch); const rollDegrees = Cesium.Math.toDegrees(roll); return { heading: headingDegrees, pitch: pitchDegrees, roll: rollDegrees, }; } /* 获取camera高度 */ function getHeight() { if (viewer) { var scene = viewer.scene; var ellipsoid = scene.globe.ellipsoid; var height = ellipsoid.cartesianToCartographic(viewer.camera.position) .height; return height; } } /* 获取camera中心点坐标 */ function getCenterPosition() { var result = viewer.camera.pickEllipsoid( new Cesium.Cartesian2( viewer.canvas.clientWidth / 2, viewer.canvas.clientHeight / 2, ), ); var curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(result); var lon = (curPosition.longitude * 180) / Math.PI; var lat = (curPosition.latitude * 180) / Math.PI; var height = getHeight(); return { lon: lon, lat: lat, height: height, }; } 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); } // 当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.height = Math.ceil(viewer.camera.positionCartographic.height); return [extent.xmin, extent.ymin, extent.xmax, extent.ymax]; } const onSubmit = () => { let propertyData = viewer.container.getElementsByClassName("cesium-geocoder-input cesium-geocoder-input-wide")[0] extent = getCurrentExtent(); orientation = getOrientation(); position = getCenterPosition(); if (handleType == 'add') { if (propertyData && propertyData.value) { var areaName = propertyData.value; let mapSettings = { camera: { mode: '3d', position, orientation }, areaName, extent } confirmModal && confirmModal(mapSettings) } else { message.info("未选择视角,请先选择区域") } } else if (handleType == 'update') { let areaName if (propertyData && propertyData.value) { areaName = propertyData.value } else if(item.mapSettings && item.mapSettings.areaName) { areaName = item.mapSettings.areaName } else { return message.info("未选择视角,请先选择区域") } let mapSettings = { camera: { mode: '3d', position, orientation }, areaName, extent } confirmModal && confirmModal(mapSettings) } } const filter = (inputValue, path) => { return path.some(option => option.name.toLowerCase().indexOf(inputValue.toLowerCase()) > -1) } return ( <Modal title='视角选择' bodyStyle={{ width: '100%', minHeight: '400px' }} style={{ top: '180px' }} width="700px" destroyOnClose maskClosable={false} cancelText="取消" okText="确认" {...props} onOk={() => onSubmit()} confirmLoading={loading} forceRender={true} getContainer={false} > {visible && (<> <div ref={el} style={{ width: '100%', height: '400px' }} > </div></>)}</Modal> ); } export default MapScope