|
@@ -0,0 +1,424 @@
|
|
|
+<template>
|
|
|
+ <div class="container">
|
|
|
+ <el-row style="height:50px;">
|
|
|
+ <div class="header" >
|
|
|
+ <el-button :type="(this.dimension==2?'success':'danger')" @click="dimensionswitch(2)" round>二维</el-button>
|
|
|
+ <el-button :type="(this.dimension==3?'success':'danger')" @click="dimensionswitch(3)" round>三维</el-button>
|
|
|
+ <el-button :type="(this.dimension==5?'success':'danger')" @click="dimensionswitch(5)" round>一体化</el-button>
|
|
|
+ </div>
|
|
|
+ </el-row>
|
|
|
+ <el-row style="height:calc(100% - 50px);display:flex;position: relative;">
|
|
|
+ <el-col style="height:100%;position: relative;" :span="this.leftwidth" >
|
|
|
+ <div class="main-layout" v-on:mouseover="changeActive('3D')">
|
|
|
+ <div id="3DcesiumContainer" class="map"></div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col style="height:100%;position: relative;" :span="(24-this.leftwidth)" >
|
|
|
+ <div class="main-layout" v-on:mouseover="changeActive('2D')">
|
|
|
+ <div id="2DcesiumContainer" class="map"></div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-tabs type="border-card" v-model="activeName" tab-position="left" class="menu" :stretch="true" @tab-click="legendClick">
|
|
|
+ <el-tab-pane name="first">
|
|
|
+ <span slot="label">
|
|
|
+ <el-tooltip class="item" effect="dark" content="标绘" placement="left">
|
|
|
+ <i class="el-icon-wind-power"></i>
|
|
|
+ </el-tooltip>
|
|
|
+ </span>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane name="second">
|
|
|
+ <span slot="label">
|
|
|
+ <el-tooltip class="item" effect="dark" content="模型" placement="left">
|
|
|
+ <i class="el-icon-receiving"></i>
|
|
|
+ </el-tooltip>
|
|
|
+ </span>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ <div class="buttons">
|
|
|
+ <el-button icon="el-icon-full-screen" circle @click="ismax()"></el-button>
|
|
|
+ <el-button icon="el-icon-coin" circle></el-button>
|
|
|
+ <el-button icon="el-icon-bangzhu" @click="Fly()" circle></el-button>
|
|
|
+ <el-button icon="el-icon-house" circle @click="home()"></el-button>
|
|
|
+ <el-button icon="el-icon-plus" circle @click="big()"></el-button>
|
|
|
+ <el-button icon="el-icon-minus" circle @click="small()"></el-button>
|
|
|
+ </div>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <script>
|
|
|
+ import screenfull from "screenfull";
|
|
|
+ export default ({
|
|
|
+ computed: {
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ viewer2D: null,
|
|
|
+ viewer3D: null,
|
|
|
+ dimension: 3,
|
|
|
+ leftwidth: 0,
|
|
|
+ mousevalue: null,
|
|
|
+ shouldAnimate: false,
|
|
|
+ activeName: 'first',
|
|
|
+ currentLab: {
|
|
|
+ index: -1,
|
|
|
+ isActive: false
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+
|
|
|
+ this.cesiumInit();
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ methods: {
|
|
|
+
|
|
|
+ cesiumInit() {
|
|
|
+ this.viewer2D = new this.Cesium.Viewer("2DcesiumContainer", {
|
|
|
+ sceneMode: this.Cesium.SceneMode.SCENE2D,
|
|
|
+ animation: false, // 是否显示时间轴动画
|
|
|
+ baseLayerPicker: false,
|
|
|
+ homeButton: false,
|
|
|
+ geocoder: false,
|
|
|
+ timeline: false,
|
|
|
+ fullscreenButton: false,
|
|
|
+ sceneModePicker: false,
|
|
|
+ navigationHelpButton: false,
|
|
|
+ selectionIndicator: false,
|
|
|
+ imageryProvider: new this.Cesium.UrlTemplateImageryProvider({
|
|
|
+ url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
|
|
|
+ layer: "tdtVecBasicLayer",
|
|
|
+ style: "default",
|
|
|
+ format: "image/png",
|
|
|
+ tileMatrixSetID: "GoogleMapsCompatible",
|
|
|
+ show: false
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ this.viewer3D = new this.Cesium.Viewer('3DcesiumContainer', {
|
|
|
+ animation: false, // 是否显示时间轴动画
|
|
|
+ baseLayerPicker: false,
|
|
|
+ homeButton: false,
|
|
|
+ geocoder: false,
|
|
|
+ timeline: false,
|
|
|
+ fullscreenButton: false,
|
|
|
+ sceneModePicker: false,
|
|
|
+ navigationHelpButton: false,
|
|
|
+ selectionIndicator: false,
|
|
|
+ // imageryProvider: new this.Cesium.WebMapServiceImageryProvider({
|
|
|
+ // url: '/geoserver/map/wms',
|
|
|
+ // // 这里是自定义的图层名称
|
|
|
+ // layers: 'map',
|
|
|
+ // parameters: {
|
|
|
+ // service: 'WMS',
|
|
|
+ // format: 'image/png',
|
|
|
+ // transparent: true
|
|
|
+ // }
|
|
|
+ // }),
|
|
|
+
|
|
|
+ imageryProvider:
|
|
|
+ // new this.Cesium.WebMapTileServiceImageryProvider({
|
|
|
+ // url: "http://10.170.16.95:8080/geoserver/gwc/service/wmts/rest/map:map/{style}/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png",
|
|
|
+ // layer: 'map:map',
|
|
|
+ // style: 'raster',
|
|
|
+ // format: 'image/png',
|
|
|
+ // tileMatrixSetID: 'EPSG:900913', //一般使用EPSG:3857坐标系
|
|
|
+
|
|
|
+ // }),
|
|
|
+ new this.Cesium.UrlTemplateImageryProvider({
|
|
|
+ url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
|
|
|
+ layer: "tdtVecBasicLayer",
|
|
|
+ style: "default",
|
|
|
+ format: "image/png",
|
|
|
+ tileMatrixSetID: "GoogleMapsCompatible",
|
|
|
+ show: false
|
|
|
+ })
|
|
|
+ });
|
|
|
+
|
|
|
+ this.viewer3D._cesiumWidget._creditContainer.style.display = "none";
|
|
|
+ this.viewer2D._cesiumWidget._creditContainer.style.display = "none";
|
|
|
+ this.viewer3D.camera.setView({
|
|
|
+ destination: new this.Cesium.Cartesian3.fromDegrees(117.918977,25.0,1500000),
|
|
|
+ // 方向,俯视和仰视的视角
|
|
|
+ // orientation:{
|
|
|
+ // heading: this.Cesium.Math.toRadians(90),//坐标系旋转90度
|
|
|
+ // pitch: this.Cesium.Math.toRadians(-45) ,//设置俯仰角度为-45度
|
|
|
+ // }
|
|
|
+ })
|
|
|
+ this.viewer2D.camera.setView({
|
|
|
+ destination: new this.Cesium.Cartesian3.fromDegrees(117.918977,25.0,1500000),
|
|
|
+ // 方向,俯视和仰视的视角
|
|
|
+ // orientation:{
|
|
|
+ // heading: this.Cesium.Math.toRadians(90),//坐标系旋转90度
|
|
|
+ // pitch: this.Cesium.Math.toRadians(-45) ,//设置俯仰角度为-45度
|
|
|
+ // }
|
|
|
+ })
|
|
|
+ // this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 1500000; //相机高度的最大值
|
|
|
+ this.viewer2D.camera.percentageChanged = 0.01;
|
|
|
+ this.viewer2D.camera.changed.addEventListener(this.sync);
|
|
|
+ this.viewer3D.camera.percentageChanged = 0.01;
|
|
|
+ this.viewer3D.camera.changed.addEventListener(this.sync);
|
|
|
+ },
|
|
|
+ removeAllModel(){
|
|
|
+ this.viewer.entities.removeAll(); // 移除全部模型
|
|
|
+ },
|
|
|
+ sync() {
|
|
|
+
|
|
|
+ if(this.mousevalue=='3D'){
|
|
|
+ // 三维地图中心点
|
|
|
+ let center = new this.Cesium.Cartesian2(
|
|
|
+ Math.floor(this.viewer3D.canvas.clientWidth / 2),
|
|
|
+ Math.floor(this.viewer3D.canvas.clientHeight / 2)
|
|
|
+ );
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 转为世界坐标系
|
|
|
+ let position = this.viewer3D.scene.camera.pickEllipsoid(center);
|
|
|
+ console.log(position);
|
|
|
+ // 判断中心点是否在椭球体上
|
|
|
+ if (this.Cesium.defined(position)) {
|
|
|
+
|
|
|
+ // 获取三维地图中心点与相机之间的距离
|
|
|
+ let distance = this.Cesium.Cartesian3.distance(
|
|
|
+ position,
|
|
|
+ this.viewer3D.scene.camera.positionWC
|
|
|
+ );
|
|
|
+ position = this.convertWorldToCartographic(position)
|
|
|
+ // 更新二维地图
|
|
|
+ this.viewer2D.scene.camera.setView({
|
|
|
+ destination: new this.Cesium.Cartesian3.fromDegrees(position.longitude,position.latitude,distance),
|
|
|
+ })
|
|
|
+ console.log(distance);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(this.mousevalue=='2D'){
|
|
|
+ // 二维地图中心点
|
|
|
+ let center = new this.Cesium.Cartesian2(
|
|
|
+ Math.floor(this.viewer2D.canvas.clientWidth / 2),
|
|
|
+ Math.floor(this.viewer2D.canvas.clientHeight / 2)
|
|
|
+ );
|
|
|
+ // 转为世界坐标系
|
|
|
+ let position = this.viewer2D.scene.camera.pickEllipsoid(center);
|
|
|
+ console.log(position);
|
|
|
+ // 判断中心点是否在椭球体上
|
|
|
+ if (this.Cesium.defined(position)) {
|
|
|
+
|
|
|
+ // 获取三维地图中心点与相机之间的距离
|
|
|
+ let distance = this.viewer2D.scene.camera.positionCartographic.height;
|
|
|
+
|
|
|
+ position = this.convertWorldToCartographic(position)
|
|
|
+ // 更新三维地图
|
|
|
+ this.viewer3D.scene.camera.setView({
|
|
|
+ destination: new this.Cesium.Cartesian3.fromDegrees(position.longitude,position.latitude,distance),
|
|
|
+ })
|
|
|
+ console.log(this.viewer2D.scene.camera.positionWC)
|
|
|
+ }
|
|
|
+ }},
|
|
|
+ // 将世界坐标系转换为经纬度坐标系
|
|
|
+ convertWorldToCartographic(worldPosition) {
|
|
|
+ const ellipsoid = this.viewer2D.scene.globe.ellipsoid;
|
|
|
+ const cartographic = ellipsoid.cartesianToCartographic(worldPosition);
|
|
|
+ const longitude = this.Cesium.Math.toDegrees(cartographic.longitude);
|
|
|
+ const latitude = this.Cesium.Math.toDegrees(cartographic.latitude);
|
|
|
+ const height = cartographic.height;
|
|
|
+ return { longitude, latitude, height };
|
|
|
+ },
|
|
|
+ // 监听地图变化
|
|
|
+ changeActive(value){
|
|
|
+ this.mousevalue = value
|
|
|
+ console.log(value)
|
|
|
+ },
|
|
|
+ dimensionswitch(value){
|
|
|
+ this.dimension = value
|
|
|
+ if(value == 3) {
|
|
|
+ this.leftwidth = 24;
|
|
|
+ }else if(value == 2){
|
|
|
+ this.leftwidth = 0;
|
|
|
+
|
|
|
+ }else{
|
|
|
+ this.leftwidth = 12;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //全屏缩小
|
|
|
+ ismax(){
|
|
|
+ if(screenfull.isEnabled && screenfull.isFullscreen){
|
|
|
+ screenfull.exit();
|
|
|
+ }else{
|
|
|
+ screenfull.request();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /* 获取camera中心点坐标 */
|
|
|
+ getCenterPosition () {
|
|
|
+ var result = this.viewer2D.camera.pickEllipsoid(new this.Cesium.Cartesian2(this.viewer2D.canvas.clientWidth / 2, this.viewer2D.canvas
|
|
|
+ .clientHeight / 2))
|
|
|
+ var curPosition = this.Cesium.Ellipsoid.WGS84.cartesianToCartographic(result)
|
|
|
+ var lon = curPosition.longitude * 180 / Math.PI
|
|
|
+ var lat = curPosition.latitude * 180 / Math.PI
|
|
|
+ var height = this.viewer2D.camera.positionCartographic.height
|
|
|
+ return {
|
|
|
+ lon: lon,
|
|
|
+ lat: lat,
|
|
|
+ height: height
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /* 地图放大 */
|
|
|
+ big () {
|
|
|
+ // 镜头拉进
|
|
|
+ this.viewer2D.camera.flyTo({
|
|
|
+ destination: this.Cesium.Cartesian3.fromDegrees(this.getCenterPosition().lon, this.getCenterPosition().lat, this.getCenterPosition().height / 1.8),
|
|
|
+ duration: 1.0
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /* 地图缩小 */
|
|
|
+ small () {
|
|
|
+ // 镜头远离
|
|
|
+ this.viewer2D.camera.flyTo({
|
|
|
+ destination: this.Cesium.Cartesian3.fromDegrees(this.getCenterPosition().lon, this.getCenterPosition().lat, this.getCenterPosition().height * 1.2),
|
|
|
+ duration: 1.0
|
|
|
+ })
|
|
|
+ },
|
|
|
+ home () {
|
|
|
+ this.viewer2D.camera.flyTo({
|
|
|
+ destination: this.Cesium.Cartesian3.fromDegrees(117.918977,25.0,1500000)
|
|
|
+ });
|
|
|
+ },
|
|
|
+ Fly() {
|
|
|
+ this.shouldAnimate = !this.shouldAnimate
|
|
|
+ this.viewer2D.clock.shouldAnimate = true
|
|
|
+ this.viewer3D.clock.shouldAnimate = true
|
|
|
+ if(this.shouldAnimate == true){
|
|
|
+ this.startRun({ multiplier: 2000 })
|
|
|
+ }else{
|
|
|
+ this.stopRun()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ startRun (option = { multiplier: 1 }) {
|
|
|
+ // 监听每次渲染前执行矩阵求解
|
|
|
+ this.viewer3D.scene.postUpdate.addEventListener(this.rotateSetting)
|
|
|
+ // 根据option修改一些参数
|
|
|
+ if (this.viewer3D.clock) {
|
|
|
+ const keys = Object.keys(option)
|
|
|
+ for (let k of keys) {
|
|
|
+ this.viewer3D.clock[k] = option[k]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ stopRun () {
|
|
|
+ let viewer = this.viewer3D
|
|
|
+ viewer.clock.multiplier = 1
|
|
|
+ viewer.scene.postUpdate.removeEventListener(this.rotateSetting)
|
|
|
+ },
|
|
|
+ rotateSetting () {
|
|
|
+ let Cesium = this.Cesium
|
|
|
+ let viewer = this.viewer3D
|
|
|
+ if (!viewer || viewer.scene.mode !== Cesium.SceneMode.SCENE3D) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(
|
|
|
+ viewer.clock.currentTime
|
|
|
+ )
|
|
|
+ // icrfToFixed 在上面的方法中,若没加载好所需的计算资源会返回undefined,判断下
|
|
|
+ if (Cesium.defined(icrfToFixed)) {
|
|
|
+ const camera = viewer.camera
|
|
|
+ const offset = Cesium.Cartesian3.clone(camera.position)
|
|
|
+ const transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed)
|
|
|
+ camera.lookAtTransform(transform, offset)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //// tabs 切换点击
|
|
|
+ legendClick(tab, event) {
|
|
|
+
|
|
|
+ var tab_content = document.querySelectorAll(".menu .el-tabs__content");
|
|
|
+ if (this.currentLab.index == tab.index) {
|
|
|
+ tab_content[0].style.display == 'none'|| ''? tab_content[0].style.display = 'block' : tab_content[0].style.display = 'none';
|
|
|
+ }
|
|
|
+ if (this.currentLab.index != tab.index) {
|
|
|
+ this.currentLab.index = tab.index;
|
|
|
+ tab_content[0].style.display = 'block';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+ </script>
|
|
|
+ <style scoped>
|
|
|
+ .header{
|
|
|
+ background-color: #1c222b;
|
|
|
+ color: #fff;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items:center;/*由于flex-direction: column,因此align-items代表的是水平方向*/
|
|
|
+ justify-content: center;/*由于flex-direction: column,因此justify-content代表的是垂直方向*/
|
|
|
+ }
|
|
|
+ .header .el-button{
|
|
|
+ width: 150px;
|
|
|
+ margin: 0 10px;
|
|
|
+ height:30px;
|
|
|
+ padding: 1px 23px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .box-card {
|
|
|
+ min-height: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ /deep/ .el-card__body {
|
|
|
+ height: 100% !important;
|
|
|
+ padding: 0px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ .main-layout {
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .container {
|
|
|
+ height: 100%;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ .map {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .menu{
|
|
|
+ position: absolute;
|
|
|
+ height: 400px;
|
|
|
+ z-index: 999;
|
|
|
+ left: 20px;
|
|
|
+ top: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ /deep/.el-tabs--left .el-tabs__header.is-left {
|
|
|
+ margin-right: unset !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .buttons{
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-items: center;
|
|
|
+ position: absolute;
|
|
|
+ z-index: 999;
|
|
|
+ right: 20px;
|
|
|
+ top: 20px;
|
|
|
+ }
|
|
|
+ .el-button{
|
|
|
+ margin: 5px !important;
|
|
|
+ }
|
|
|
+ </style>
|