智慧农业大数据平台
shuishen
2022-07-07 441fdb5805131a0e8580b07a5b00660dd4550212
遥感监测相关
4 files modified
7 files added
1269 ■■■■■ changed files
package-lock.json 21 ●●●●● patch | view | raw | blame | history
package.json 1 ●●●● patch | view | raw | blame | history
public/img/icon/left.png patch | view | raw | blame | history
public/img/icon/lump.png patch | view | raw | blame | history
public/img/icon/right.png patch | view | raw | blame | history
public/img/icon/roller-close.png patch | view | raw | blame | history
src/components/remote/index.vue 463 ●●●●● patch | view | raw | blame | history
src/components/splitScreen/index.vue 437 ●●●●● patch | view | raw | blame | history
src/components/timeLine/index.vue 336 ●●●●● patch | view | raw | blame | history
src/main.js 3 ●●●●● patch | view | raw | blame | history
src/views/monitor/index.vue 8 ●●●●● patch | view | raw | blame | history
package-lock.json
@@ -1947,7 +1947,7 @@
        },
        "ansi-styles": {
          "version": "4.3.0",
          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
          "dev": true,
          "optional": true,
@@ -1957,7 +1957,7 @@
        },
        "chalk": {
          "version": "4.1.2",
          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
          "dev": true,
          "optional": true,
@@ -1968,7 +1968,7 @@
        },
        "color-convert": {
          "version": "2.0.1",
          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
          "dev": true,
          "optional": true,
@@ -1978,21 +1978,21 @@
        },
        "color-name": {
          "version": "1.1.4",
          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
          "dev": true,
          "optional": true
        },
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
          "dev": true,
          "optional": true
        },
        "loader-utils": {
          "version": "2.0.2",
          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.2.tgz",
          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
          "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
          "dev": true,
          "optional": true,
@@ -2013,7 +2013,7 @@
        },
        "supports-color": {
          "version": "7.2.0",
          "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
          "dev": true,
          "optional": true,
@@ -2023,7 +2023,7 @@
        },
        "vue-loader-v16": {
          "version": "npm:vue-loader@16.8.3",
          "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
          "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
          "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
          "dev": true,
          "optional": true,
@@ -13005,6 +13005,11 @@
      "integrity": "sha1-UylVzB6yCKPZkLOp+acFdGV+CPI=",
      "dev": true
    },
    "vue-jsonp": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/vue-jsonp/-/vue-jsonp-2.0.0.tgz",
      "integrity": "sha512-Mzd9GNeuKP5hHFDWZNMWOsCuMILSkA6jo2l4A02wheFz3qqBzH7aSEFTey1BRCZCLizlaf1EqJ5YUtF392KspA=="
    },
    "vue-loader": {
      "version": "15.9.8",
      "resolved": "https://registry.npmmirror.com/vue-loader/download/vue-loader-15.9.8.tgz",
package.json
@@ -30,6 +30,7 @@
        "tippy.js": "^6.3.7",
        "vue": "^2.6.11",
        "vue-axios": "^3.3.7",
        "vue-jsonp": "^2.0.0",
        "vue-router": "^3.5.2",
        "vuex": "^3.6.2"
    },
public/img/icon/left.png
public/img/icon/lump.png
public/img/icon/right.png
public/img/icon/roller-close.png
src/components/remote/index.vue
New file
@@ -0,0 +1,463 @@
/* eslint-disable camelcase */
<template>
    <div style="height: 100%; width: 100%; position: relative;">
        <div class="location-box">
            <el-input
                placeholder="请输入地点/经纬度:113.25,30.53"
                v-model="location"
                class="input-with-select"
            >
                <el-button slot="append" @click="setLocation" icon="el-icon-search"></el-button>
            </el-input>
        </div>
        <div class="tool-box">
            <div class="measure" v-show="screenShow">
                <div class="btn">
                    <span>
                        <i class="el-icon-time"></i>
                    </span>
                    标注
                </div>
            </div>
            <div class="measure" v-show="!screenShow">
                <div class="btn">
                    <span>
                        <i class="el-icon-time"></i>
                    </span>
                    标注
                </div>
                <div class="line"></div>
                <div class="btn" @click="distanceSurface">
                    <span>
                        <i class="el-icon-copy-document"></i>
                    </span>
                    测距
                </div>
                <div class="line"></div>
                <div class="btn" @click="areaSurface">
                    <span>
                        <i class="el-icon-menu"></i>
                    </span>
                    测面
                </div>
            </div>
            <div v-show="!rollerCloseShow && !screenShow" class="func">
                <div class="btn">
                    <span>
                        <i class="el-icon-time"></i>
                    </span>
                    多时相
                </div>
                <div class="line"></div>
                <div class="btn" @click="rollerShutters">
                    <span>
                        <i class="el-icon-copy-document"></i>
                    </span>
                    卷帘
                </div>
                <div class="line"></div>
                <div class="btn" @click="splitScreen">
                    <span>
                        <i class="el-icon-menu"></i>
                    </span>
                    分屏
                </div>
            </div>
            <div class="roller-close" @click="closeRollerShutters" v-show="rollerCloseShow"></div>
            <div class="screen-close" @click="closeSplitScreen" v-show="screenShow"></div>
        </div>
        <div v-show="!screenShow" id="viewer-container" style="height: 100%; width: 100%"></div>
        <split-screen v-if="screenShow"></split-screen>
        <div
            v-if="!rollerCloseShow && !screenShow"
            style="position: fixed; top: auto; left: 0; right: 0; bottom: 44px; margin: auto; width: 610px; height: 68px;"
        >
            <time-line></time-line>
        </div>
    </div>
</template>
<script>
let baselayerElc = null
let num = 0
export default {
    name: 'remote',
    data () {
        return {
            rollerCloseShow: false,
            screenShow: false,
            location: ''
        }
    },
    computed: {
    },
    mounted () {
        if (global.viewer != null) {
            global.viewer = null
        }
        function initViewer () {
            global.viewer = new global.DC.Viewer('viewer-container', {
                contextOptions: {
                    webgl: {
                        alpha: true,
                        stencil: true,
                        preserveDrawingBuffer: true
                    }
                }
            })
            if (global.DC.Namespace.Cesium.FeatureDetection.supportsImageRenderingPixelated()) { // 判断是否支持图像渲染像素化处理
                global.viewer.setOptions({
                    resolutionScale: window.devicePixelRatio
                })
            }
            // 影像
            global.viewer.imageryLayers.addImageryProvider(
                new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
                    url: 'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e9533f5acb2ac470b07f406a4d24b4f0',
                    subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                    format: 'image/jpeg',
                    show: true,
                    maximumLevel: 18
                })
            )
            // http://arcgis.jxpskj.com:6080/arcgis/rest/services/nanchengdom/MapServer
            global.viewer.imageryLayers.addImageryProvider(
                new global.DC.Namespace.Cesium.WebMapTileServiceImageryProvider({
                    url: 'http://arcgis.jxpskj.com:6080/arcgis/rest/services/nanchengyjjddom/MapServer/WMTS',
                    // url: 'http://arcgis.jxpskj.com:6080/arcgis/rest/services/nanchengdom/MapServer/WMTS',
                    layer: 'nanchengyjjddom',
                    style: 'default',
                    tileMatrixSetID: 'default028mm',
                    format: 'image/png',
                    tilingScheme: new global.DC.Namespace.Cesium.GeographicTilingScheme(),
                    maximumLevel: 19,
                    tileMatrixLabels: [
                        '0',
                        '1',
                        '2',
                        '3',
                        '4',
                        '5',
                        '6',
                        '7',
                        '8',
                        '9',
                        '10',
                        '11',
                        '12',
                        '13',
                        '14',
                        '15',
                        '16',
                        '17',
                        '18',
                        '19'
                    ]
                })
            )
            global.viewer.imageryLayers.addImageryProvider(
                new global.DC.Namespace.Cesium.WebMapTileServiceImageryProvider({
                    url: 'http://arcgis.jxpskj.com:6080/arcgis/rest/services/nanchengdom/MapServer/WMTS',
                    // url: 'http://arcgis.jxpskj.com:6080/arcgis/rest/services/nanchengdom/MapServer/WMTS',
                    layer: 'nanchengdom',
                    style: 'default',
                    tileMatrixSetID: 'default028mm',
                    format: 'image/png',
                    tilingScheme: new global.DC.Namespace.Cesium.GeographicTilingScheme(),
                    maximumLevel: 19,
                    tileMatrixLabels: [
                        '0',
                        '1',
                        '2',
                        '3',
                        '4',
                        '5',
                        '6',
                        '7',
                        '8',
                        '9',
                        '10',
                        '11',
                        '12',
                        '13',
                        '14',
                        '15',
                        '16',
                        '17',
                        '18',
                        '19'
                    ]
                })
            )
            // 矢量电子
            // global.viewer.imageryLayers.addImageryProvider(
            //     new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
            //         url: 'http://t{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e9533f5acb2ac470b07f406a4d24b4f0',
            //         subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
            //         format: 'image/jpeg',
            //         show: true,
            //         maximumLevel: 18
            //     })
            // )
            // global.viewer.imageryLayers.addImageryProvider(
            //     new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
            //         url: 'http://t{s}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e9533f5acb2ac470b07f406a4d24b4f0',
            //         subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
            //         format: 'image/jpeg',
            //         show: true,
            //         maximumLevel: 18
            //     })
            // )
            global.viewer.use(new global.DC.Measure())
            global.viewer.camera.setView({
                // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
                // fromDegrees()方法,将经纬度和高程转换为世界坐标
                destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
                    116.56705776, 27.42386903, 1800.0
                ),
                orientation: {
                    // 指向
                    heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
                    // 视角
                    pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
                    roll: 0.0
                }
            })
            // global.viewer.locationBar.enable = true
        }
        global.DC.ready(initViewer)
    },
    methods: {
        // 根据地址获取坐标
        addrToGetCoordinate (addr) {
            const that = this
            this.$jsonp('https://apis.map.qq.com/ws/geocoder/v1/', {
                key: '6POBZ-M3HK2-RMPU5-C6F4L-M3YTK-GTFVU',
                output: 'jsonp',
                address: addr
            })
                .then((res) => {
                    console.log(res)
                    if (res.status === 0) {
                        // 用获取到的经纬度,修改地图的中心点
                        global.viewer.camera.flyTo({
                            // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
                            // fromDegrees()方法,将经纬度和高程转换为世界坐标
                            destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
                                res.result.location.lng.toFixed(6), res.result.location.lat.toFixed(6), 1800.0
                            ),
                            orientation: {
                                // 指向
                                heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
                                // 视角
                                pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
                                roll: 0.0
                            },
                            duration: 3,
                            complete () {
                                that.location = ''
                            }
                        })
                    } else {
                        that.$message(res.message)
                        that.location = ''
                    }
                })
                .catch((e) => {
                    that.$message(e)
                })
        },
        setLocation () {
            const longreg = /^(\-|\+)?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,15})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,15}|180)$/
            const latreg = /^(\-|\+)?([0-8]?\d{1}\.\d{0,15}|90\.0{0,15}|[0-8]?\d{1}|90)$/
            const that = this
            // 验证是否是中文
            var pattern = new RegExp('[\u4E00-\u9FA5]+')
            // 验证是否是英文
            var pattern2 = new RegExp('[A-Za-z]+')
            if (pattern.test(this.location) || pattern2.test(this.location)) {
                this.addrToGetCoordinate(this.location)
                return
            }
            if (this.location.indexOf(',') != -1 || this.location.indexOf(',') != -1) {
                let arr
                if (this.location.indexOf(',') != -1) {
                    arr = this.location.split(',')
                } else {
                    arr = this.location.split(',')
                }
                if (arr.length > 2) {
                    this.$message('格式错误!')
                } else {
                    if (!longreg.test(arr[0])) {
                        this.$message('经度整数部分为0-180,小数部分为0到15位!')
                    } else if (!latreg.test(arr[1])) {
                        this.$message('纬度整数部分为0-90,小数部分为0到15位!')
                    } else {
                        global.viewer.camera.flyTo({
                            // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
                            // fromDegrees()方法,将经纬度和高程转换为世界坐标
                            destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
                                arr[0], arr[1], 1800.0
                            ),
                            orientation: {
                                // 指向
                                heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
                                // 视角
                                pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
                                roll: 0.0
                            },
                            duration: 3,
                            complete () {
                                that.location = ''
                            }
                        })
                    }
                }
            } else {
                this.$message('格式错误!')
            }
        },
        closeSplitScreen () {
            this.screenShow = false
        },
        splitScreen () {
            this.screenShow = true
        },
        distanceSurface () {
            global.viewer.measure.distanceSurface()
        },
        areaSurface () {
            global.viewer.measure.areaSurface()
        },
        rollerShutters () {
            if (num == 0) {
                baselayerElc = global.DC.ImageryLayerFactory.createTdtImageryLayer({
                    key: 'e9533f5acb2ac470b07f406a4d24b4f0'
                })
                global.viewer.mapSplit.enable = true
                global.viewer.mapSplit.addBaseLayer(baselayerElc)
            } else {
                global.viewer.mapSplit.enable = true
            }
            num++
            this.rollerCloseShow = true
        },
        closeRollerShutters () {
            global.viewer.mapSplit.enable = false
            this.rollerCloseShow = false
        }
    }
}
</script>
<style lang="scss" scoped>
.eagle-eye-map {
    position: fixed;
    right: 10px;
    bottom: 10px;
    border: 5px solid orange;
    border-radius: 50%;
    width: 200px;
    height: 200px;
    z-index: 99;
    overflow: hidden;
}
.location-box {
    position: absolute;
    top: 25px;
    left: 50px;
    z-index: 9;
    width: 320px;
}
.tool-box {
    display: flex;
    justify-content: space-between;
    position: absolute;
    top: 25px;
    right: 25px;
    z-index: 9;
    & > div {
        display: flex;
        align-items: center;
        height: 40px;
        background: #fff;
        border-radius: 4px;
        overflow: hidden;
        .btn {
            width: 74px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 12px;
            color: #717171;
            cursor: pointer;
            i {
                margin-right: 6px;
                vertical-align: middle !important;
            }
        }
        .line {
            width: 0px;
            height: 24px;
            border-right: 1px dashed #dcdee1;
        }
    }
    .roller-close,
    .screen-close {
        margin-left: 30px;
        width: 40px;
        height: 40px;
        background: url(/img/icon/roller-close.png) no-repeat;
        background-size: 100% 100%;
    }
    .func {
        margin-left: 10px;
    }
}
</style>
src/components/splitScreen/index.vue
New file
@@ -0,0 +1,437 @@
/* eslint-disable camelcase */
<template>
    <div class="current-wrapper" style="height: 100%; width: 100%; position: relative;">
        <div class="map-box" id="viewer-container-one"></div>
        <div class="map-box" id="viewer-container-two"></div>
        <div class="map-box" id="viewer-container-three"></div>
        <div class="map-box" id="viewer-container-four"></div>
        <div class="line-row"></div>
        <div class="line-column"></div>
    </div>
</template>
<script>
let viewerOne = null
let viewerTwo = null
let viewerThree = null
let viewerFour = null
let handlerTL = null
let handlerTR = null
let handlerBL = null
let handlerBR = null
export default {
    name: 'splitScreen',
    data () {
        return {
            rollerCloseShow: false
        }
    },
    computed: {
    },
    mounted () {
        const that = this
        this.$nextTick(() => {
            function initViewer () {
                viewerOne = new global.DC.Viewer('viewer-container-one', {
                    contextOptions: {
                        webgl: {
                            alpha: true,
                            stencil: true,
                            preserveDrawingBuffer: true
                        }
                    }
                })
                viewerTwo = new global.DC.Viewer('viewer-container-two', {
                    contextOptions: {
                        webgl: {
                            alpha: true,
                            stencil: true,
                            preserveDrawingBuffer: true
                        }
                    }
                })
                viewerThree = new global.DC.Viewer('viewer-container-three', {
                    contextOptions: {
                        webgl: {
                            alpha: true,
                            stencil: true,
                            preserveDrawingBuffer: true
                        }
                    }
                })
                viewerFour = new global.DC.Viewer('viewer-container-four', {
                    contextOptions: {
                        webgl: {
                            alpha: true,
                            stencil: true,
                            preserveDrawingBuffer: true
                        }
                    }
                })
                if (global.DC.Namespace.Cesium.FeatureDetection.supportsImageRenderingPixelated()) { // 判断是否支持图像渲染像素化处理
                    viewerOne.setOptions({
                        resolutionScale: window.devicePixelRatio
                    })
                    viewerTwo.setOptions({
                        resolutionScale: window.devicePixelRatio
                    })
                    viewerThree.setOptions({
                        resolutionScale: window.devicePixelRatio
                    })
                    viewerFour.setOptions({
                        resolutionScale: window.devicePixelRatio
                    })
                }
                // 影像
                viewerOne.imageryLayers.addImageryProvider(
                    new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
                        url: 'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e9533f5acb2ac470b07f406a4d24b4f0',
                        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                        format: 'image/jpeg',
                        show: true,
                        maximumLevel: 18
                    })
                )
                viewerTwo.imageryLayers.addImageryProvider(
                    new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
                        url: 'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e9533f5acb2ac470b07f406a4d24b4f0',
                        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                        format: 'image/jpeg',
                        show: true,
                        maximumLevel: 18
                    })
                )
                viewerThree.imageryLayers.addImageryProvider(
                    new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
                        url: 'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e9533f5acb2ac470b07f406a4d24b4f0',
                        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                        format: 'image/jpeg',
                        show: true,
                        maximumLevel: 18
                    })
                )
                viewerFour.imageryLayers.addImageryProvider(
                    new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
                        url: 'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e9533f5acb2ac470b07f406a4d24b4f0',
                        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                        format: 'image/jpeg',
                        show: true,
                        maximumLevel: 18
                    })
                )
                viewerOne.imageryLayers.addImageryProvider(
                    new global.DC.Namespace.Cesium.WebMapTileServiceImageryProvider({
                        url: 'http://arcgis.jxpskj.com:6080/arcgis/rest/services/nanchengyjjddom/MapServer/WMTS',
                        // url: 'http://arcgis.jxpskj.com:6080/arcgis/rest/services/nanchengdom/MapServer/WMTS',
                        layer: 'nanchengyjjddom',
                        style: 'default',
                        tileMatrixSetID: 'default028mm',
                        format: 'image/png',
                        tilingScheme: new global.DC.Namespace.Cesium.GeographicTilingScheme(),
                        maximumLevel: 19,
                        tileMatrixLabels: [
                            '0',
                            '1',
                            '2',
                            '3',
                            '4',
                            '5',
                            '6',
                            '7',
                            '8',
                            '9',
                            '10',
                            '11',
                            '12',
                            '13',
                            '14',
                            '15',
                            '16',
                            '17',
                            '18',
                            '19'
                        ]
                    })
                )
                viewerOne.imageryLayers.addImageryProvider(
                    new global.DC.Namespace.Cesium.WebMapTileServiceImageryProvider({
                        url: 'http://arcgis.jxpskj.com:6080/arcgis/rest/services/nanchengdom/MapServer/WMTS',
                        // url: 'http://arcgis.jxpskj.com:6080/arcgis/rest/services/nanchengdom/MapServer/WMTS',
                        layer: 'nanchengdom',
                        style: 'default',
                        tileMatrixSetID: 'default028mm',
                        format: 'image/png',
                        tilingScheme: new global.DC.Namespace.Cesium.GeographicTilingScheme(),
                        maximumLevel: 19,
                        tileMatrixLabels: [
                            '0',
                            '1',
                            '2',
                            '3',
                            '4',
                            '5',
                            '6',
                            '7',
                            '8',
                            '9',
                            '10',
                            '11',
                            '12',
                            '13',
                            '14',
                            '15',
                            '16',
                            '17',
                            '18',
                            '19'
                        ]
                    })
                )
                // 矢量电子
                // global.viewer.imageryLayers.addImageryProvider(
                //     new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
                //         url: 'http://t{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e9533f5acb2ac470b07f406a4d24b4f0',
                //         subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                //         format: 'image/jpeg',
                //         show: true,
                //         maximumLevel: 18
                //     })
                // )
                // global.viewer.imageryLayers.addImageryProvider(
                //     new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
                //         url: 'http://t{s}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e9533f5acb2ac470b07f406a4d24b4f0',
                //         subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                //         format: 'image/jpeg',
                //         show: true,
                //         maximumLevel: 18
                //     })
                // )
                that.initHandler(viewerOne, viewerTwo, viewerThree, viewerFour)
                viewerOne.camera.setView({
                    // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
                    // fromDegrees()方法,将经纬度和高程转换为世界坐标
                    destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
                        116.56705776, 27.42386903, 1800.0
                    ),
                    orientation: {
                        // 指向
                        heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
                        // 视角
                        pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
                        roll: 0.0
                    }
                })
                viewerTwo.camera.setView({
                    // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
                    // fromDegrees()方法,将经纬度和高程转换为世界坐标
                    destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
                        116.56705776, 27.42386903, 1800.0
                    ),
                    orientation: {
                        // 指向
                        heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
                        // 视角
                        pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
                        roll: 0.0
                    }
                })
                viewerThree.camera.setView({
                    // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
                    // fromDegrees()方法,将经纬度和高程转换为世界坐标
                    destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
                        116.56705776, 27.42386903, 1800.0
                    ),
                    orientation: {
                        // 指向
                        heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
                        // 视角
                        pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
                        roll: 0.0
                    }
                })
                viewerFour.camera.setView({
                    // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
                    // fromDegrees()方法,将经纬度和高程转换为世界坐标
                    destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
                        116.56705776, 27.42386903, 1800.0
                    ),
                    orientation: {
                        // 指向
                        heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
                        // 视角
                        pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
                        roll: 0.0
                    }
                })
                // global.viewer.locationBar.enable = true
            }
            global.DC.ready(initViewer)
        })
    },
    methods: {
        cameraSetView (viewer, camera) {
            viewer.camera.setView({
                destination: camera.position,
                orientation: {
                    direction: camera._direction,
                    up: camera.up,
                    heading: camera.heading,
                    pitch: camera.pitch,
                    roll: camera.roll
                }
            })
        },
        initMovement (handler, viewer0, viewer1, viewer2, viewer3) {
            const that = this
            handler.setInputAction(function (movement) {
                const camera = viewer0.camera
                that.cameraSetView(viewer1, camera)
                that.cameraSetView(viewer2, camera)
                that.cameraSetView(viewer3, camera)
            }, global.DC.Namespace.Cesium.ScreenSpaceEventType.MOUSE_MOVE)
            handler.setInputAction(function (movement) {
                const camera = viewer0.camera
                that.cameraSetView(viewer1, camera)
                that.cameraSetView(viewer2, camera)
                that.cameraSetView(viewer3, camera)
            }, global.DC.Namespace.Cesium.ScreenSpaceEventType.WHEEL)
        },
        initHandler (viewer0, viewer1, viewer2, viewer3) {
            const that = this
            if (handlerTL != null ||
                handlerTR != null ||
                handlerBL != null ||
                handlerBR != null) {
                return
            }
            handlerTL = new global.DC.Namespace.Cesium.ScreenSpaceEventHandler(viewer0.scene.canvas)
            handlerTR = new global.DC.Namespace.Cesium.ScreenSpaceEventHandler(viewer1.scene.canvas)
            handlerBL = new global.DC.Namespace.Cesium.ScreenSpaceEventHandler(viewer2.scene.canvas)
            handlerBR = new global.DC.Namespace.Cesium.ScreenSpaceEventHandler(viewer3.scene.canvas)
            that.initMovement(handlerTR, viewer1, viewer0, viewer2, viewer3)
            that.initMovement(handlerBL, viewer2, viewer1, viewer0, viewer3)
            that.initMovement(handlerBR, viewer3, viewer1, viewer2, viewer0)
            that.initMovement(handlerTL, viewer0, viewer1, viewer2, viewer3)
        },
        clearHandler () {
            if (handlerTR != null) {
                handlerTR.removeInputAction(global.DC.Namespace.Cesium.ScreenSpaceEventType.MOUSE_MOVE)
                handlerTR.removeInputAction(global.DC.Namespace.Cesium.ScreenSpaceEventType.WHEEL)
            }
            if (handlerBL != null) {
                handlerBL.removeInputAction(global.DC.Namespace.Cesium.ScreenSpaceEventType.MOUSE_MOVE)
                handlerBL.removeInputAction(global.DC.Namespace.Cesium.ScreenSpaceEventType.WHEEL)
            }
            if (handlerBR != null) {
                handlerBR.removeInputAction(global.DC.Namespace.Cesium.ScreenSpaceEventType.MOUSE_MOVE)
                handlerBR.removeInputAction(global.DC.Namespace.Cesium.ScreenSpaceEventType.WHEEL)
            }
            if (handlerTL != null) {
                handlerTL.removeInputAction(global.DC.Namespace.Cesium.ScreenSpaceEventType.MOUSE_MOVE)
                handlerTL.removeInputAction(global.DC.Namespace.Cesium.ScreenSpaceEventType.WHEEL)
            }
        }
    },
    destroyed () {
        this.clearHandler()
        handlerTL = null
        handlerTR = null
        handlerBL = null
        handlerBR = null
        viewerOne.destroy()
        viewerTwo.destroy()
        viewerThree.destroy()
        viewerFour.destroy()
        viewerOne = null
        viewerTwo = null
        viewerThree = null
        viewerFour = null
    }
}
</script>
<style lang="scss" scoped>
.eagle-eye-map {
    position: fixed;
    right: 10px;
    bottom: 10px;
    border: 5px solid orange;
    border-radius: 50%;
    width: 200px;
    height: 200px;
    z-index: 99;
    overflow: hidden;
}
.current-wrapper {
    display: flex;
    flex-wrap: wrap;
    .map-box {
        width: 50%;
        height: 50%;
    }
    .line-row {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
        width: 4px;
        height: 100%;
        background: #fff;
    }
    .line-column {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
        width: 100%;
        height: 4px;
        background: #fff;
    }
}
</style>
src/components/timeLine/index.vue
New file
@@ -0,0 +1,336 @@
<template>
    <!--时间线-->
    <div class="time-box">
        <div class="l-btn" @click="moveLeft">
            <img src="/img/icon/left.png" />
            <div class="year-box">{{timeLineList[0].timestamp}}</div>
        </div>
        <div class="time-line-box">
            <div class="ul_box">
                <ul ref="mytimeline" style="left: 0">
                    <li
                        v-for="(item,index) in timeLineList"
                        :key="index"
                        @click="selectTime($event, item, index)"
                    ></li>
                </ul>
            </div>
            <img ref="TimePointer" class="pointer" src="/img/icon/lump.png" style="left: 16px" alt />
            <div ref="TextPopup" class="text-popup" style="left: -36px; top: -44px;">
                {{currentObj.info}}
                <div class="arrows"></div>
            </div>
        </div>
        <div class="r-btn" @click="moveRight">
            <img src="/img/icon/right.png" />
            <div class="year-box">{{timeLineList[timeLineList.length - 1].timestamp}}</div>
        </div>
    </div>
</template>
<script>
export default {
    name: 'timeLine',
    data () {
        return {
            timeIndex: 2,
            timeLineList: [{
                timestamp: '2012',
                color: '#999',
                fontsize: 18,
                size: '28',
                bgcolor: '#e4e7ed',
                icon: 'el-iconprev',
                year: '2012',
                info: '2012第一季度'
            }, {
                timestamp: '2013年',
                color: '#999',
                fontsize: 18,
                size: '28',
                bgcolor: '#e4e7ed',
                year: '2013',
                info: '2012第二季度'
            }, {
                timestamp: '2014年',
                color: '#999',
                fontsize: 18,
                size: '28',
                bgcolor: '#e4e7ed',
                year: '2014',
                info: '2012第三季度'
            }, {
                timestamp: '2015年',
                color: '#999',
                fontsize: 18,
                year: '2015',
                size: '28',
                bgcolor: '#e4e7ed',
                info: '2012第四季度'
            }, {
                timestamp: '2016年',
                color: '#999',
                fontsize: 18,
                size: '28',
                year: '2016',
                bgcolor: '#e4e7ed',
                info: '2013第一季度'
            }, {
                timestamp: '2017年',
                color: '#999',
                fontsize: 18,
                size: '28',
                bgcolor: '#e4e7ed',
                year: '2017',
                info: '2013第二季度'
            }, {
                timestamp: '2018年',
                color: '#999',
                fontsize: 18,
                size: '28',
                bgcolor: '#e4e7ed',
                year: '2018',
                info: '2013第三季度'
            }, {
                timestamp: '2019年',
                color: '#999',
                fontsize: 18,
                year: '2019',
                bgcolor: '#e4e7ed',
                size: '28',
                info: '2013第四季度'
            }, {
                timestamp: '2019年',
                color: '#999',
                fontsize: 18,
                year: '2019',
                bgcolor: '#e4e7ed',
                size: '28',
                info: '2014第一季度'
            }, {
                timestamp: '2019年',
                color: '#999',
                fontsize: 18,
                year: '2019',
                bgcolor: '#e4e7ed',
                size: '28',
                info: '2014第二季度'
            }, {
                timestamp: '2019年',
                color: '#999',
                fontsize: 18,
                year: '2019',
                bgcolor: '#e4e7ed',
                size: '28',
                info: '2014第三季度'
            }, {
                timestamp: '2019年',
                color: '#999',
                fontsize: 18,
                year: '2019',
                bgcolor: '#e4e7ed',
                size: '28',
                info: '2014第四季度'
            }, {
                timestamp: '2019',
                color: '#999',
                fontsize: 18,
                year: '2019',
                bgcolor: '#e4e7ed',
                size: '28',
                info: '2015第一季度'
            }],
            currentObj: {
                timestamp: '2012',
                color: '#999',
                fontsize: 18,
                size: '28',
                bgcolor: '#e4e7ed',
                icon: 'el-iconprev',
                year: '2012',
                info: '2012第一季度'
            },
            currentInd: 0,
            leftStart: false,
            rightStart: true
        }
    },
    methods: {
        selectTime (e, item, index) {
            this.currentObj = item
            this.currentInd = index
            if (parseInt(this.$refs.mytimeline.style.left) < 0) {
                this.$refs.TimePointer.style.left = e.target.offsetLeft + parseInt(this.$refs.mytimeline.style.left) + 14 + 'px'
                this.$refs.TextPopup.style.left = e.target.offsetLeft + parseInt(this.$refs.mytimeline.style.left) - 38 + 'px'
            } else {
                if (e.target.offsetLeft <= 528) {
                    this.$refs.TimePointer.style.left = e.target.offsetLeft + 14 + 'px'
                    this.$refs.TextPopup.style.left = e.target.offsetLeft - 38 + 'px'
                }
            }
            // offsetX
        },
        changeActive (index) {
            this.timeIndex = index
        },
        moveLeft () {
            const leftWidth = parseInt(this.$refs.mytimeline.style.left)
            const boxWidth = parseInt(this.$refs.mytimeline.clientWidth)
            if (this.leftStart == false) {
                return
            } else {
                this.rightStart = true
            }
            if (this.currentInd <= 0) return
            this.currentInd = this.currentInd - 1
            this.currentObj = this.timeLineList[this.currentInd]
            if (leftWidth <= 0 && Math.abs(leftWidth) <= boxWidth - 528) {
                if (leftWidth + 48 < 0) {
                    this.$refs.mytimeline.style.left = leftWidth + 48 + 'px'
                } else {
                    this.$refs.mytimeline.style.left = 0 + 'px'
                    this.leftStart = false
                }
            }
        },
        moveRight () {
            const leftWidth = parseInt(this.$refs.mytimeline.style.left)
            const boxWidth = parseInt(this.$refs.mytimeline.clientWidth)
            if (this.rightStart == false) {
                return
            } else {
                this.leftStart = true
            }
            if (this.currentInd >= this.timeLineList.length - 1) return
            this.currentInd = this.currentInd + 1
            this.currentObj = this.timeLineList[this.currentInd]
            if (leftWidth <= 0 && Math.abs(leftWidth) <= boxWidth - 528) {
                if (Math.abs(leftWidth - 48) < boxWidth - 528) {
                    this.$refs.mytimeline.style.left = leftWidth - 48 + 'px'
                } else {
                    this.$refs.mytimeline.style.left = -(boxWidth - 528) + 'px'
                    this.rightStart = false
                }
            }
        }
    }
}
</script>
<style  lang="scss" scoped>
.time-box {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.8);
    border-radius: 8px 8px 8px 8px;
    .l-btn,
    .r-btn {
        display: flex;
        align-items: center;
        justify-content: center;
        position: relative;
        flex: 1;
        height: 80%;
        img {
            width: 20px;
        }
        .year-box {
            position: absolute;
            bottom: 0;
            font-size: 12px;
            font-weight: bold;
            color: #515252;
        }
    }
    .time-line-box {
        position: relative;
        width: 528px;
        height: 16px;
        .ul_box {
            position: relative;
            width: 528px;
            height: 16px;
            overflow-x: hidden;
            display: flex;
            border-radius: 8px 8px 8px 8px;
            ul {
                position: absolute;
                display: flex;
                flex-wrap: nowrap;
                li {
                    margin: 0 2px;
                    width: 44px;
                    height: 16px;
                    background: #4d7bda;
                    cursor: pointer;
                }
                // li:first-child {
                //     margin-left: 0;
                // }
                // li:last-child {
                //     margin-right: 0;
                // }
            }
        }
        .pointer {
            position: absolute;
            top: 10px;
            width: 16px;
            z-index: 1;
        }
        .text-popup {
            position: absolute;
            width: 120px;
            line-height: 36px;
            z-index: 1;
            background: #fff;
            font-size: 12px;
            color: #333333;
            border-radius: 4px;
            box-shadow: 0px 3px 6px 1px rgba(0, 0, 0, 0.16);
            .arrows {
                position: absolute;
                top: auto;
                left: 0;
                right: 0;
                bottom: -18px;
                margin: auto;
                width: 0;
                height: 0;
                border-top: 9px solid #fff;
                border-left: 7px solid transparent;
                border-right: 7px solid transparent;
                border-bottom: 9px solid transparent;
            }
        }
    }
}
</style>
src/main.js
@@ -18,6 +18,7 @@
// fade/zoom 等
import 'element-ui/lib/theme-chalk/base.css'
import { VueJsonp } from 'vue-jsonp'
import DC from '@dvgis/dc-sdk/dist/dc.base.min' // 基础包
import DcCore from '@dvgis/dc-sdk/dist/dc.core.min' // 核心包
@@ -41,6 +42,8 @@
DC.use(DcMapv) // 安装Mapv库
DC.use(DcS3M) // 安装DcS3M库
Vue.use(VueJsonp)
Vue.use(ElementUI)
Vue.use(VueAxios, axios)
src/views/monitor/index.vue
@@ -2,15 +2,13 @@
 * @Author: Morpheus
 * @Date: 2022-05-11 15:00:23
 * @Last Modified by: Morpheus
 * @Last Modified time: 2022-07-01 09:58:34
 * @Last Modified time: 2022-07-07 16:41:07
 * 农产品监管
 */
<template>
    <div class="container">
        <mapBox ref="modalForm" />
        <div class="popup">
            <img src="/img/jc.png" alt />
        </div>
        <remote ref="modalForm" />
        <!-- <div class="l-echarts">
            <div class="t-box">
                <div class="title">