index.jsx 7.35 KB
Newer Older
1 2 3
import React, { useEffect, useState, useRef } from 'react'
import { Input, Button, Modal, message } from 'antd'
import { gcj_decrypt, exetent2AmapPoint, lngLat2WebMercator } from '@/utils/transformUtil'
邓超's avatar
邓超 committed
4
import { GetAllConfig, GetMetaData } from '@/services/gis/gis'
邹绪超's avatar
邹绪超 committed
5 6 7 8
import {
    PdRender,
    Cesium,
} from '@wisdom-cesium/cesium'
9 10 11
const { Search } = Input;
let pdViewer, viewer, extent, orientation, position;
const MapScope = props => {
邹绪超's avatar
邹绪超 committed
12
    const { visible, confirmModal,item , baseMapData, baseMap, handleType} = props;
13 14 15 16 17
    const [options, setOptions] = useState([])
    let el = useRef(null);
    const [loading, setLoading] = useState(false);
    let buttonEl = useRef(null);

邹绪超's avatar
邹绪超 committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
    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 {}
        }
    }
44 45
    useEffect(() => {
        if (visible) {
邹绪超's avatar
邹绪超 committed
46
            pdViewer = new PdRender({
47
                el: el.current,
邹绪超's avatar
邹绪超 committed
48 49
                baseMaps : getBaseMap() || [] ,
                cameraSetting : getCamera () || {}
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
            });
            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 = () => {
邹绪超's avatar
邹绪超 committed
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
        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("未选择视角,请先选择区域")
            }
shaoan123's avatar
shaoan123 committed
180
            let mapSettings = { camera: { mode: '3d', position, orientation }, areaName, extent }
181
            confirmModal && confirmModal(mapSettings)
邹绪超's avatar
邹绪超 committed
182
        } 
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
    }
    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