上饶市警务平台后台管理前端
guoshilong
2023-02-15 6cfa3b57cc57b564af6e60376ac88592a8c8b99b
地图变更为DC地图
6 files modified
2 files added
552 ■■■■ changed files
package.json 1 ●●●● patch | view | raw | blame | history
src/components/map/dcMap.vue 157 ●●●●● patch | view | raw | blame | history
src/components/map/dcSearchMap.vue 169 ●●●●● patch | view | raw | blame | history
src/components/map/searchMap.vue 80 ●●●● patch | view | raw | blame | history
src/main.js 27 ●●●● patch | view | raw | blame | history
src/views/range/range.vue 6 ●●●●● patch | view | raw | blame | history
src/views/security/security.vue 11 ●●●● patch | view | raw | blame | history
vue.config.js 101 ●●●●● patch | view | raw | blame | history
package.json
@@ -18,6 +18,7 @@
    "babel-polyfill": "^6.26.0",
    "classlist-polyfill": "^1.2.0",
    "crypto-js": "^4.0.0",
    "echarts": "^5.4.1",
    "element-ui": "^2.15.6",
    "js-base64": "^2.5.1",
    "js-cookie": "^2.2.0",
src/components/map/dcMap.vue
New file
@@ -0,0 +1,157 @@
<template>
  <div>
    <div id="viewer-container" :style="{ height: isDetail ? '95vh' : '40vh', width: '100%' }"></div>
    <div style="position: absolute;right:45%;top:-1%;z-index: 999999">
      <p style="margin-top: 10px" v-if="!isDetail">
        <el-button type="primary" size="small" @click="draw('polygon')">绘制区域</el-button>
        <el-button size="small" @click="clearDraw">重置</el-button>
      </p>
    </div>
  </div>
</template>
<script>
export default {
  name: "dcMap",
  props:['isDetail','range'],
  data(){
    return{
      polygonLayer:null,
      polyLineLayer:null,
      polygon:null,
      polyLine:null,
      //绘制工具
      plotTool:null,
      coordinates:[]
    }
  },
  created() {
  },
  mounted() {
    let self = this
    global.DC.ready(() => {
      initViewer()
    })
    function initViewer() {
      //配置viewer
      global.viewer = new global.DC.Viewer('viewer-container',{
        contextOptions: {
          webgl: {
            alpha: true,
            stencil: true,
            preserveDrawingBuffer: true
          }
        },
        sceneMode:2
      })
      //加载地图
      global.viewer.imageryLayers.addImageryProvider(
        new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
          url: 'https://webmap-tile.sf-express.com/MapTileService/rt?fetchtype=static&x={x}&y={y}&z={z}&project=sfmap&pic_size=256&pic_type=png8&data_name=361100&data_format=merged-dat&data_type=normal',
          format: 'image/jpeg',
          show: true,
          maximumLevel: 18
        })
      )
      //添加图层
      self.polygonLayer = new global.DC.VectorLayer('polygonLayer')
      global.viewer.addLayer(self.polygonLayer)
      //添加图层
      self.polyLineLayer = new global.DC.VectorLayer('polyLineLayer')
      global.viewer.addLayer(self.polyLineLayer)
      self.plotTool = new global.DC.Plot(global.viewer)
      //初始化定位
      global.viewer.camera.setView({
        // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
        // fromDegrees()方法,将经纬度和高程转换为世界坐标
        destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
          //设置坐标为上饶市
          117.951478782, 28.447896798, 1800.0
        ),
        orientation: {
          // 指向
          heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
          // 视角
          pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
          roll: 0.0
        }
      })
    }
    if (this.isDetail){
      this.showPolyLine(this.range)
    }
  },
  methods:{
    //开始绘画
    draw(type){
      if (this.polygon){
        this.clearDraw()
      }
      this.plotTool && this.plotTool.draw(type,overlay => {
        if(overlay){
          this.polygonLayer.addOverlay(overlay)
          overlay.positions.forEach(e=>{
            this.coordinates.push([e.lng,e.lat])
          })
          let toData = this.doData(this.coordinates)
          this.$emit('toData', toData)
        }
      })
    },
    //重置
    clearDraw(){
      this.polygonLayer.clear()
    },
    //转换成数据库数据
    doData(val) {
      let str = "LINESTRING("
      for (let k = 0; k < val.length; k++) {
        str += `${val[k][0]} ${val[k][1]}`
        if (k != val.length - 1) {
          str += ","
        }
      }
      str = str + "," + `${val[0][0]} ${val[0][1]}`
      str += ")"
      // console.log(str)
      return '\'' + str + '\''
    },
    //回显多边形
    showPolygon(positions){
      let viewer = global.viewer
      positions = positions.replaceAll(",",";").replaceAll(" ",",")
      this.polygon = new global.DC.Polygon(positions)
      this.polygon.setStyle({
        material: DC.Color.RED
      })
      this.polygonLayer.addOverlay(this.polygon)
      viewer.flyTo(this.polygonLayer)
    },
    //回显线
    showPolyLine(positions){
      let viewer = global.viewer
      positions = positions.replaceAll(",",";").replaceAll(" ",",")
      this.polyLine = new global.DC.Polyline(positions)
      this.polyLine.setStyle({
        material: DC.Color.RED
      })
      this.polyLineLayer.addOverlay(this.polyLine)
      viewer.flyTo(this.polyLineLayer)
    }
  }
}
</script>
<style scoped>
</style>
src/components/map/dcSearchMap.vue
New file
@@ -0,0 +1,169 @@
<template>
  <div>
    <div id="search-viewer-container" style="height: 100%; width: 100%"></div>
  </div>
</template>
<script>
export default {
  name: "dcSearchMap",
  props: ['isDetail','point'],
  data() {
    return {
      pointLayer: null,
      currentPoint:null,
      //绘制工具
      plotTool: null,
      coordinates: []
    }
  },
  created() {
  },
  mounted() {
  },
  methods: {
    init(){
      let self = this
      if (global.viewer != null) {
        global.viewer = null
      }
      global.DC.ready(() => {
        initViewer()
      })
      function initViewer() {
        //配置viewer
        global.viewer = new global.DC.Viewer('search-viewer-container', {
          contextOptions: {
            webgl: {
              alpha: true,
              stencil: true,
              preserveDrawingBuffer: true
            }
          },
          sceneMode: 2
        })
        //加载地图
        global.viewer.imageryLayers.addImageryProvider(
          new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
            url: 'https://webmap-tile.sf-express.com/MapTileService/rt?fetchtype=static&x={x}&y={y}&z={z}&project=sfmap&pic_size=256&pic_type=png8&data_name=361100&data_format=merged-dat&data_type=normal',
            format: 'image/jpeg',
            show: true,
            maximumLevel: 18
          })
        )
        //添加图层
        self.pointLayer = new global.DC.VectorLayer('polygonLayer')
        global.viewer.addLayer(self.pointLayer)
        self.plotTool = new global.DC.Plot(global.viewer,{
          icon_center: "/img/dwicon.jpeg", // 自定义的中心点图标
          icon_anchor: "/img/dwicon.jpeg", //自定义的锚点图标
          icon_midAnchor: "/img/dwicon.jpeg", //自定义的中心锚点图标
          icon_size: [12, 12],//自定义的中心锚点大小
          clampToModel:false // 点位是否获取模型表面坐标
        })
        //初始化定位
        global.viewer.camera.setView({
          // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
          // fromDegrees()方法,将经纬度和高程转换为世界坐标
          destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
            //设置坐标为上饶市
            117.951478782, 28.447896798, 1800.0
          ),
          orientation: {
            // 指向
            heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
            // 视角
            pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
            roll: 0.0
          }
        })
      }
      this.showPoint(this.point)
      this.draw()
    },
    //开始绘画
    draw() {
      const self = this
      if (this.polygon) {
        this.clearDraw()
      }
      //鼠标左键事件
      let leftClick = function (event) {
        if (self.currentPoint){
          self.pointLayer.removeOverlay(self.currentPoint)
          self.currentPoint = null
        }
        let point = new global.DC.Point(new global.DC.Position(event.wgs84SurfacePosition.lng, event.wgs84SurfacePosition.lat))
        point.setStyle({
          pixelSize: 10,
          color: global.DC.Color.RED, //颜色
          outlineColor: global.DC.Color.WHITE, //边框颜色
          outlineWidth: 2, //边框大小,
        })
        self.currentPoint = point
        self.pointLayer.addOverlay(point)
        let pointLonLat = [event.wgs84SurfacePosition.lng,event.wgs84SurfacePosition.lat]
        self.$emit("getMapData", pointLonLat)
      }
      //添加鼠标左键事件
      global.viewer.on(global.DC.MouseEventType.LEFT_DOWN,leftClick)
    },
    //重置
    clearDraw() {
      this.polygonLayer.clear()
    },
    //转换成数据库数据
    doData(val) {
      let str = "LINESTRING("
      for (let k = 0; k < val.length; k++) {
        str += `${val[k][0]} ${val[k][1]}`
        if (k != val.length - 1) {
          str += ","
        }
      }
      str = str + "," + `${val[0][0]} ${val[0][1]}`
      str += ")"
      // console.log(str)
      return '\'' + str + '\''
    },
    //回显点
    showPoint(positions) {
      let viewer = global.viewer
      if (positions){
        let pointData = ""
        let pointArray = []
        pointData = positions.match(/\(([^)]*)\)/)
        pointArray = pointData[1].split(" ")
        let position = new global.DC.Position(pointArray[0],pointArray[1])
        let point = new global.DC.Point(position)
        point.setStyle({
          pixelSize: 10,
          color: global.DC.Color.RED, //颜色
          outlineColor: global.DC.Color.WHITE, //边框颜色
          outlineWidth: 2, //边框大小,
        })
        this.currentPoint = point
        this.pointLayer.addOverlay(point)
        viewer.flyTo(this.pointLayer)
      }
    },
  }
}
</script>
<style scoped>
</style>
src/components/map/searchMap.vue
@@ -2,26 +2,26 @@
  <div class="basic-container">
    <div class="search-line">
      <el-select
            class="search-input"
            v-model="queryString"
            filterable
            remote
            reserve-keyword
            placeholder="请输入关键词"
            :remote-method="remoteMethod"
            :loading="loading"
            @change="selectChange">
            <el-option
              v-for="item in searchList"
              :key="item.uid"
              :label="item.address"
              :value="JSON.stringify(item)">
            </el-option>
          </el-select>
<!--      <el-button class="search-button" @click="getAddressByQuery">查询</el-button>-->
        class="search-input"
        v-model="queryString"
        filterable
        remote
        reserve-keyword
        placeholder="请输入关键词"
        :remote-method="remoteMethod"
        :loading="loading"
        @change="selectChange">
        <el-option
          v-for="item in searchList"
          :key="item.uid"
          :label="item.address"
          :value="JSON.stringify(item)">
        </el-option>
      </el-select>
      <!--      <el-button class="search-button" @click="getAddressByQuery">查询</el-button>-->
    </div>
    <search-map-box ref="OpenLayersMap" @getMapData="getMapData" :route-range="point"
                    :is-detail="true"></search-map-box>
    <!--    <search-map-box ref="OpenLayersMap" @getMapData="getMapData" :route-range="point" :is-detail="true"></search-map-box>-->
    <dc-search-map ref="dcSearchMap" @getMapData="getMapData" :point="point"></dc-search-map>
  </div>
</template>
@@ -29,27 +29,28 @@
import SearchMapBox from "@/components/map/searchMapBox";
import {getAoiByPt, search, searchByLonLat, searchByQuery} from "@/api/security/security";
import data from "@/views/util/data";
import DcSearchMap from "@/components/map/dcSearchMap";
export default {
  name: "searchMap",
  components: {SearchMapBox},
  components: {DcSearchMap, SearchMapBox},
  props: ['pointLonLat'],
  data() {
    return {
      ak:"ebf48ecaa1fd436fa3d40c4600aa051f",
      region:"361100",
      ak: "ebf48ecaa1fd436fa3d40c4600aa051f",
      region: "361100",
      longitude: "",
      latitude: "",
      queryString: "",
      point: "",
      searchList:[],
      loading:false,
      searchList: [],
      loading: false,
    }
  },
  watch:{
    longitude:{
      handler(newVal){
        if (newVal){
  watch: {
    longitude: {
      handler(newVal) {
        if (newVal) {
          this.getAddressByLonLat()
        }
      }
@@ -58,13 +59,16 @@
  created() {
    this.point = this.pointLonLat
  },
  mounted() {
    this.$refs.dcSearchMap.init()
  },
  methods: {
    getMapData(data) {
      this.longitude = data[0][0]
      this.latitude = data[0][1]
      this.$emit("getLonLat", data[0])
      this.longitude = data[0]
      this.latitude = data[1]
      this.$emit("getLonLat", data)
    },
    remoteMethod(data){
    remoteMethod(data) {
      this.queryString = data
      this.getAddressByQuery()
    },
@@ -73,12 +77,12 @@
      let region = this.region
      let query = this.queryString
      let ids = "61743e28bbf11700e9fc4ef03dd8bea9"
      searchByQuery(ak,region,query,ids).then(res => {
      searchByQuery(ak, region, query, ids).then(res => {
        let dataList = res.data.result
        this.searchList = dataList
      })
    },
    getAddressByLonLat(){
    getAddressByLonLat() {
      let ak = this.ak
      let query = ""
      let region = this.region
@@ -87,14 +91,14 @@
      let page_num = "1"
      let infos = 1
      let radius = 500
      let location = this.longitude+" "+this.latitude
      searchByLonLat(ak,query,region,region_type,page_size,page_num,infos,radius,location).then(res=>{
      let location = this.longitude + " " + this.latitude
      searchByLonLat(ak, query, region, region_type, page_size, page_num, infos, radius, location).then(res => {
        let data = res.data.result[0]
        this.queryString = data.address
        this.$emit("getAddress",this.queryString)
        this.$emit("getAddress", this.queryString)
      })
    },
    selectChange(data){
    selectChange(data) {
      let selectData = JSON.parse(data)
      this.$refs.OpenLayersMap.setView(selectData.location)
    }
src/main.js
@@ -4,9 +4,9 @@
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2023-02-07 10:39:07
 * @FilePath: \srs-police-web\src\main.js
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */
import Vue from 'vue'
import axios from './router/axios'
@@ -36,6 +36,27 @@
// 业务组件
import tenantPackage from './views/system/tenantpackage'
import * as echarts from 'echarts'
Vue.prototype.$echarts = echarts
import DC from '@dvgis/dc-sdk/dist/dc.base.min' //基础包
import DcCore from '@dvgis/dc-sdk/dist/dc.core.min' //核心包
import DcChart from '@dvgis/dc-sdk/dist/dc.chart.min' //chart包
import DcMapv from '@dvgis/dc-sdk/dist/dc.mapv.min' //mapv包
import DcS3M from '@dvgis/dc-sdk/dist/dc.s3m.min' //s3m包
import '@dvgis/dc-sdk/dist/dc.core.min.css' // 主要样式
global.DC = DC // 将DC提升到全局变量,方便在工程中直接使用
global.viewer = null // 将viewer提升到全局变量,方便在工程中直接使用
global.echarts = echarts // 将DC提升到全局变量,方便在工程中直接使用
DC.use(DcCore) // 安装DC核心库
DC.use(DcChart) // 安装DC图标库,使用前确保echarts为全局函数
DC.use(DcMapv) // 安装Mapv库
DC.use(DcS3M) // 安装DcS3M库
// 注册全局crud驱动
window.$crudCommon = crudCommon
// 加载Vue拓展
src/views/range/range.vue
@@ -41,7 +41,8 @@
      size="60%"
      direction="rtl"
      :before-close="handleClose">
      <map-box v-if="isDetail" :is-detail="isDetail" :route-range="routeRange"></map-box>
<!--      <map-box v-if="isDetail" :is-detail="isDetail" :route-range="routeRange"></map-box>-->
      <dc-map ref="dcMap" v-if="isDetail" :is-detail="isDetail" :range="routeRange"></dc-map>
    </el-drawer>
  </basic-container>
</template>
@@ -50,9 +51,10 @@
  import {getList, getDetail, add, update, remove} from "@/api/range/range";
  import {mapGetters} from "vuex";
  import MapBox from "@/components/map/mapBox";
  import DcMap from "@/components/map/dcMap";
  export default {
    components: {MapBox},
    components: {DcMap, MapBox},
    data() {
      return {
        form: {},
src/views/security/security.vue
@@ -19,7 +19,8 @@
        </el-button>
      </template>
      <template slot="activityAreaForm">
        <map-box ref="OpenLayersMap" @toData="toData" :routeRange="form.activityArea"></map-box>
<!--        <map-box ref="OpenLayersMap" @toData="toData" :routeRange="form.activityArea"></map-box>-->
        <dc-map ref="dcMap" @toData="toData" :range="form.activityArea"></dc-map>
      </template>
    </avue-crud>
@@ -55,9 +56,11 @@
import securityManageCar from "@/views/securityManageCar/securityManageCar"
import MapBox from "@/components/map/mapBox";
import SearchMap from "@/components/map/searchMap";
import DcMap from "@/components/map/dcMap";
export default {
  components: {
    DcMap,
    SearchMap,
    MapBox,
    securityManage,
@@ -339,10 +342,7 @@
        loading()
        return
      }
      if (row.activityArea.startsWith("LINESTRING")){
      }else {
      if (!row.activityArea.startsWith("'LINESTRING")){
        row.activityArea = "'LINESTRING("+row.activityArea+")'"
      }
      row.position = row.longitude + " " + row.latitude
@@ -405,6 +405,7 @@
          this.form['longitude'] = data.position.split(" ")[0]
          this.form['latitude'] = data.position.split(" ")[1]
          this.point = "POINT("+this.form.longitude +" "+this.form.latitude+")"
          this.$refs.dcMap.showPolygon(this.form.activityArea)
        })
      }
      done()
vue.config.js
@@ -8,48 +8,67 @@
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */
const path = require('path')
const CopywebpackPlugin = require('copy-webpack-plugin')
const dvgisDist = './node_modules/@dvgis'
module.exports = {
    //路径前缀
    publicPath: "/",
    lintOnSave: true,
    productionSourceMap: false,
    chainWebpack: (config) => {
        //忽略的打包文件
        config.externals({
            'vue': 'Vue',
            'vue-router': 'VueRouter',
            'vuex': 'Vuex',
            'axios': 'axios',
            'element-ui': 'ELEMENT',
        })
        const entry = config.entry('app')
        entry.add('babel-polyfill').end()
        entry.add('classlist-polyfill').end()
        entry.add('@/mock').end()
    },
    css: {
        extract: { ignoreOrder: true }
    },
    //开发模式反向代理配置,生产模式请使用Nginx部署并配置反向代理
    devServer: {
        port: 1888,
        proxy: {
            '/api': {
                //本地服务接口地址
                target: 'http://localhost:82',
                //远程演示服务地址,可用于直接启动项目
                //target: 'https://saber.bladex.vip/api',
                ws: true,
                pathRewrite: {
                    '^/api': '/'
                }
            },
          'bsapi': {
              target: 'http://192.168.0.112:9091',
              pathRewrite: {
                '^/bsapi': '/'
              }
          }
  //路径前缀
  publicPath: "/",
  lintOnSave: true,
  productionSourceMap: false,
  chainWebpack: (config) => {
    config.plugin('copy').use(CopywebpackPlugin, [
      [
        {
          from: path.join(dvgisDist, 'dc-sdk/dist/resources'),
          to: 'libs/dc-sdk/resources'
        }
        // {
        //     from: './public/wp',
        //     to: 'wp'
        // },
        // {
        //     from: './public/qx',
        //     to: 'qx'
        // }
      ]
    ])
    //忽略的打包文件
    config.externals({
      'vue': 'Vue',
      'vue-router': 'VueRouter',
      'vuex': 'Vuex',
      'axios': 'axios',
      'element-ui': 'ELEMENT',
    })
    const entry = config.entry('app')
    entry.add('babel-polyfill').end()
    entry.add('classlist-polyfill').end()
    entry.add('@/mock').end()
  },
  css: {
    extract: {ignoreOrder: true}
  },
  //开发模式反向代理配置,生产模式请使用Nginx部署并配置反向代理
  devServer: {
    port: 1888,
    proxy: {
      '/api': {
        //本地服务接口地址
        target: 'http://localhost:82',
        //远程演示服务地址,可用于直接启动项目
        //target: 'https://saber.bladex.vip/api',
        ws: true,
        pathRewrite: {
          '^/api': '/'
        }
      },
      'bsapi': {
        target: 'http://192.168.0.112:9091',
        pathRewrite: {
          '^/bsapi': '/'
        }
      }
    }
  }
}