Newer
Older
smartcity_merchant_front / src / components / Map / arcgisMapShop.vue
wangxitong on 22 Feb 2024 15 KB first commit
<template>
  <div style="margin-top:-30px">
    <!-- <el-row :gutter="20">
      <el-col :span="4">
        <el-input v-model="keywords" size="small" type="text" placeholder="兴趣点关键字" clearable />
      </el-col>
      <el-col :span="4">
        <el-button type="primary" size="small" @click="queryOnMap">查询</el-button>
        <el-button type="info" size="small" @click="clearMap"> 清除地图 </el-button>
      </el-col>

      <el-col :span="8" style="text-align: center;">
        <el-radio-group v-model="queryEventSwitch" size="small" @change="switchEventOrComponent">
          <el-radio-button label="1">事件定位</el-radio-button>
          <el-radio-button label="0">部件定位</el-radio-button>
          <el-radio-button label="2">兴趣点属性</el-radio-button>
        </el-radio-group>
      </el-col>

      <el-col v-if="queryEventSwitch === '0'" :span="8" style="text-align: right;">
        <el-select v-model="componentId" placeholder="选择部件" clearable value="" size="small">
          <el-option
            v-for="item in compListOpts"
            :key="item.value"
            :label="item.name"
            :value="item.value"/>
        </el-select>
        <el-button type="primary" size="small" @click="checkComponentPoint"> 部件提交 </el-button>
      </el-col>

      <el-col v-if="queryEventSwitch === '1'" :span="8" style="text-align: right;">
        <el-button type="primary" size="small" @click="checkEventPoint"> 事件提交 </el-button>
      </el-col>
    </el-row> -->

    <div v-loading="mapLoading" id="map" ref="mapDiv" class="baseMap"/>
  </div>
</template>

<script>
import { loadModules } from 'esri-loader'
import { mapConfig, serverConfig } from './ArcGISConfig'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
const option = {
  url: mapConfig.apiUrl
}

// const eventPointLayerId = 'eventPointLayer' // 事件定位点的图层id
// const queryResultLayerId = 'queryResultLayer' // 兴趣点查询结果点集的图层id
const caseLayerId = 'addedGeometryLayerId' // 案卷点图层

export default {
  name: 'ArcGisMapShop',
  props: {
    position: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      map: '',
      view: '',
      layers: {
        dxbjPoint: '', // 部件点图层
        dxbjLine: '', // 部件线图层
        dxbjXqd: '', // 兴趣点图层
        dxbjMph: '', // 门牌好图层
        dx2wGrid: '' // 单元网格图层
      },
      esriObj: {
        Map: '',
        BaseMap: '',
        Graphic: '',
        PopupTemplate: '',
        Circle: '',
        Point: '',
        FeatureLayer: '',
        GraphicsLayer: '',
        TileLayer: '',
        SimpleMarkerSymbol: '',
        Query: '',
        QueryTask: '',
        IdentifyTask: '',
        IdentifyParameters: '',
        MapView: ''
      },
      mapLoading: false
      // keywords: '', // 查询关键字
      // showEventPointPopup: true, // 是否显示事部件的popup
      // queryEventSwitch: '1', // 1==查询事件;0==查询部件
      // compListOpts: [], // 部件选择下拉框option
      // 主页面返回值
      // longitude: '', // 定位点经度
      // latitude: '' // 定位点纬度
      // communityId: '', // 社区ID
      // communityName: '', // 社区名称
      // gridId: '', // 单元网格ID
      // componentId: '', // 部件ID
      // componentName: '' // 部件名称/=
    }
  },
  mounted() {
    // this.importEsri()
    this.initMap()
  },
  methods: {
    // 初始化ArcGIS API对象
    importEsri: function() {
      this.mapLoading = true
      loadModules([
        'esri/Map',
        'esri/Basemap',
        'esri/Graphic',
        'esri/PopupTemplate',
        'esri/geometry/Circle',
        'esri/geometry/Point',
        'esri/layers/FeatureLayer',
        'esri/layers/GraphicsLayer',
        'esri/layers/TileLayer',
        'esri/symbols/SimpleMarkerSymbol',
        'esri/tasks/support/Query',
        'esri/tasks/QueryTask',
        'esri/tasks/IdentifyTask',
        'esri/tasks/support/IdentifyParameters',
        'esri/views/MapView',
        'dojo/domReady!'
      ], option)
        .then(([
          Map,
          BaseMap,
          Graphic,
          PopupTemplate,
          Circle,
          Point,
          FeatureLayer,
          GraphicsLayer,
          TileLayer,
          SimpleMarkerSymbol,
          Query,
          QueryTask,
          IdentifyTask,
          IdentifyParameters,
          MapView
        ]) => {
          this.esriObj.Map = Map
          this.esriObj.BaseMap = BaseMap
          this.esriObj.Graphic = Graphic
          this.esriObj.PopupTemplate = PopupTemplate
          this.esriObj.Circle = Circle
          this.esriObj.Point = Point
          this.esriObj.FeatureLayer = FeatureLayer
          this.esriObj.GraphicsLayer = GraphicsLayer
          this.esriObj.TileLayer = TileLayer
          this.esriObj.SimpleMarkerSymbol = SimpleMarkerSymbol
          this.esriObj.Query = Query
          this.esriObj.QueryTask = QueryTask
          this.esriObj.IdentifyTask = IdentifyTask
          this.esriObj.IdentifyParameters = IdentifyParameters
          this.esriObj.MapView = MapView

          // 初始化地图
          this.initMap()
          this.mapLoading = false
        }).catch(err => {
          console.log(err)
          this.mapLoading = false
        })
    },
    // 初始化地图
    initMap: function() {
      const map = L.map('map', {
        minZoom: 3,
        maxZoom: 18,
        center: [28.24, 116.597], // 116.597, 28.24
        zoom: 3,
        zoomControl: false,
        attributionControl: false,
        crs: L.CRS.EPSG3857
      })
      this.map = map // data上需要挂载
      // window.map = map
      L.tileLayer(
        'https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8',
        { subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'] }
      ).addTo(map)
      L.tileLayer(
        'https://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8',
        { subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'] }
      ).addTo(map)

      // const base = new this.esriObj.BaseMap({
      //   baseLayers: [
      //     new this.esriObj.TileLayer({ // 可配置属性,见TileLayer类
      //       id: '2w',
      //       url: serverConfig.mapUrlBase
      //     })
      //   ],
      //   title: 'dx2w',
      //   id: 'dx2w'
      // })
      //
      // this.map = new this.esriObj.Map({
      //   basemap: base // 底图类型,详见BaseMap类
      // })
      //
      // this.view = new this.esriObj.MapView({
      //   container: this.$refs.mapDiv, // 视图的容器
      //   map: this.map, // Map的实例放入视图中
      //   center: [116.597, 28.24], // 初始显示的地图中心点,经纬度
      //   zoom: 3 // 当前地图缩放等级
      // })

      // this.addBjLayers()
      this.addCasePointOnMap(this.position)
    },
    // 加载部件服务的各图层
    addBjLayers: function() {
      // 此处可以优化
      this.layers.dxbjPoint = new this.esriObj.FeatureLayer({ // 可配置属性,见TileLayer类
        url: serverConfig.mapUrlBj + '/0',
        id: 'dxbjPoint'
      })
      this.layers.dxbjLine = new this.esriObj.FeatureLayer({ // 可配置属性,见TileLayer类
        url: serverConfig.mapUrlBj + '/1',
        id: 'dxbjLine'
      })
      this.layers.dxbjXqd = new this.esriObj.FeatureLayer({ // 可配置属性,见TileLayer类
        url: serverConfig.mapUrlBj + '/2',
        id: 'dxbjXqd'
      })
      this.layers.dxbjMph = new this.esriObj.FeatureLayer({ // 可配置属性,见TileLayer类
        url: serverConfig.mapUrlBj + '/3',
        id: 'dxbjMph'
      })
      this.layers.dx2wGrid = new this.esriObj.FeatureLayer({
        url: serverConfig.mapUrlBase + '/1',
        id: 'gridLayer'
      })

      // 加载各图层
      this.map.add(this.layers.dxbjPoint)
      this.map.add(this.layers.dxbjLine)
      this.map.add(this.layers.dxbjXqd)
      this.map.add(this.layers.dxbjMph)
      this.map.add(this.layers.dx2wGrid)
    },
    // 在兴趣点图层查询关键字
    // queryOnMap: function() {
    //   const points = [] // 查询结果点集

    //   this.clearQueryResults()
    //   this.clearEOrCPoint()
    //   this.showEventPointPopup = false
    //   this.queryEventSwitch = '2'

    //   // 查询条件
    //   const query = new this.esriObj.Query()
    //   query.returnGeometry = true
    //   query.outFields = ['*']
    //   query.where = 'NAME like ' + "'%" + this.keywords + "%'"
    //   const that = this

    //   this.layers.dxbjXqd.queryFeatures(query).then(function(results) {
    //     results.features.forEach(item => {
    //       const point = {}
    //       point.x = item.geometry.longitude
    //       point.y = item.geometry.latitude
    //       point.attr = item.attributes
    //       points.push(point)
    //     })

    //     // 提示查询结果
    //     if (points.length > 0) {
    //       that.$message({
    //         message: '成功查询到' + points.length + '条记录',
    //         type: 'success'
    //       })

    //       // 绘制点
    //       that.addSimpleMarkerOnMap(points)
    //     } else {
    //       that.$message({
    //         message: '没有查询到结果,请重新输入关键字',
    //         type: 'warning'
    //       })
    //     }
    //   })
    // },
    // 清除图层上的查询结果
    // clearQueryResults: function() {
    //   this.map.layers.forEach(layer => {
    //     if (layer.type === 'graphics' && layer.id === queryResultLayerId) {
    //       layer.graphics.removeAll()
    //       return false
    //     }
    //   })
    // },
    // // 清除图层上的查询结果
    // clearMap: function() {
    //   // 清除地图上绘制的graphic图层
    //   this.map.layers.forEach(layer => {
    //     if (layer.type === 'graphics') {
    //       layer.graphics.removeAll()
    //       return false
    //     }
    //   })

    //   // 清除弹出框
    //   this.view.popup.close()

    //   // 清除data属性值
    //   this.keywords = ''
    //   this.showEventPointPopup = true // 是否显示事部件的popup
    //   this.queryEventSwitch = '1' // 1==查询事件;0==查询部件
    //   this.compListOpts = [] // 部件选择下拉框option
    //   this.longitude = '' // 定位点经度
    //   this.latitude = '' // 定位点纬度
    //   this.communityId = '' // 社区ID
    //   this.communityName = '' // 社区名称
    //   this.gridId = '' // 单元网格ID
    //   this.componentId = '' // 部件ID
    //   this.componentName = '' // 部件名称
    // },
    // 清除图层上的事件定位点
    // clearEOrCPoint: function() {
    //   this.map.layers.forEach(layer => {
    //     if (layer.type === 'graphics' && layer.id === eventPointLayerId) {
    //       layer.graphics.removeAll()
    //       return false
    //     }
    //   })
    //   // 清除弹出框
    //   this.view.popup.close()
    // },
    // 切换
    // switchEventOrComponent: function() {
    //   // 如果选中的是事件定位(1)或部件定位(0),点击地图时弹出事件或者部件的popup;否则(2以上)显示兴趣点结果的属性popup
    //   this.showEventPointPopup = this.queryEventSwitch < 2
    // },
    // 将查询结果点集合绘制在地图上
    // addSimpleMarkerOnMap: function(points) {
    //   const gLayer = new this.esriObj.GraphicsLayer()
    //   points.forEach(item => {
    //     const point = new this.esriObj.Point(item.x, item.y, item.attr)
    //     const marker = new this.esriObj.SimpleMarkerSymbol()
    //     marker.color = '#F9690E'
    //     marker.outline = {
    //       color: [128, 128, 128, 0.5],
    //       width: '2px'
    //     }
    //     const graphic = new this.esriObj.Graphic({
    //       geometry: point,
    //       symbol: marker,
    //       attributes: item.attr
    //     })
    //     gLayer.id = queryResultLayerId
    //     gLayer.add(graphic)
    //   })
    //   this.map.add(gLayer)
    // },
    // 返回事件定位的结果
    // checkEventPoint: function() {
    //   this.$emit(
    //     'closeMapQueryDialogByEvent',
    //     this.longitude,
    //     this.latitude,
    //     this.communityId,
    //     this.communityName,
    //     this.gridId)

    //   this.clearMap()
    // },
    // // 返回部件定位的结果
    // checkComponentPoint: function() {
    //   this.$emit(
    //     'closeMapQueryDialogByComp',
    //     this.longitude,
    //     this.latitude,
    //     this.communityId,
    //     this.communityName,
    //     this.gridId,
    //     this.componentId)

    //   this.clearMap()
    // },
    // 在地图上添加指定坐标的点
    setZoom(points) {
      console.log(points)
      if (points.length > 0) {
        var maxLng = points[0][1]
        var minLng = points[0][1]
        var maxLat = points[0][0]
        var minLat = points[0][0]
        var res
        for (var i = points.length - 1; i >= 0; i--) {
          res = points[i]
          if (res[1] > maxLng) maxLng = res[1]
          if (res[1] < minLng) minLng = res[1]
          if (res[0] > maxLat) maxLat = res[0]
          if (res[0] < minLat) minLat = res[0]
        }
        var cenLng = (parseFloat(maxLng) + parseFloat(minLng)) / 2
        var cenLat = (parseFloat(maxLat) + parseFloat(minLat)) / 2
        var zoom = this.getZoom(maxLng, minLng, maxLat, minLat)
        this.map.setView({ lat: cenLat, lng: cenLng }, zoom)
      } else {
        // 没有坐标,显示全中国
        this.map.setView({ lat: 103.388611, lng: 35.563611 }, 5)
      }
    },
    getZoom(maxLng, minLng, maxLat, minLat) {
      var zoom = ['50', '100', '200', '500', '1000', '2000', '5000', '10000', '20000', '25000', '50000', '100000', '200000', '500000', '1000000', '2000000']// 级别18到3。
      var latlng = L.latLng(maxLat, maxLng)
      var distance = latlng.distanceTo(L.latLng(minLat, minLng))
      // var distance = pointA.distanceTo(pointB)// 获取两点距离,保留小数点后两位
      for (var i = 0, zoomLen = zoom.length; i < zoomLen; i++) {
        if (zoom[i] - distance > 0) {
          console.log(i)
          return 18 - i + 2 // 之所以会多2,是因为地图范围常常是比例尺距离的10倍以上。所以级别会增加3。
        }
      }
    },
    addCasePointOnMap: function(str) {
      var pathlist = []
      var points = str.split(';')
      for (var i = 0; i < points.length; i++) {
        var item = [Number(points[i].split(',')[1]), Number(points[i].split(',')[0])]
        pathlist.push(item)
      }
      if (pathlist.length !== 0) {
        var myStyle = {
          'color': '#ff3c2d',
          'weight': 4,
          'opacity': 0.7
        }
        L.polygon(pathlist, myStyle).addTo(this.map)
      }
      this.setZoom(pathlist)
      // var Icon = L.icon({
      //   iconUrl: require('../../assets/global_images/point.png'),
      //   iconSize: [15, 15]// 点大小
      // })
      // L.marker([lat, lng], {
      //   icon: Icon
      // }).addTo(this.map)
      // this.map.setView({ lat: lat, lng: lng }, 15)
    }
  }
}
</script>

<style >
  /* @import 'http://192.168.8.205/arcgis_js_api/library/4.12/esri/css/main.css'; */
  @import 'https://js.arcgis.com/4.13/esri/css/main.css';
  .baseMap {
    height:60vh;
    width: 100%;
    margin-top: 25px;
    border: 1px solid #DCDCDC;
    border-radius: 4px;
  }
</style>