需求:初始化頁面在地圖上顯示所有廠站坐標(以標注點位形式)並可點擊展示對應廠站信息。
支持搜索定位廠站(單個點擊廠站)並自動彈出相應廠站信息,清空input輸入框自動初始化地圖(全國地圖)
<template> <div class="GIS_box"> <a-button class="GIS_Button" icon="unordered-list" @click="onHandleGIS">廠站視圖</a-button> <div class="GIS_Button_left"> <div style="border-bottom:1px solid #f1f1f1;margin-bottom:10px;padding-bottom:6px" > <span style="font-weight:600;font-size:15px;margin-right:10px;">廠站列表</span> <a-icon type="info-circle" style="margin: 5px;"/>共{{total}}條</div> <a-input-search allowClear v-model="searchStr" @search="onSearch" placeholder="輸入廠站名稱關鍵字搜索" /> <!-- selectedKeys是選中項key的集合,expandedKeys是展開項key的集合 --> <a-tree v-model="checkedKeys" :expanded-keys="expandedKeys" :auto-expand-parent="autoExpandParent" :selected-keys="selectedKeys" @expand="onExpand" @select="onSelect" > <a-icon slot="icon" type="carry-out" /> <a-tree-node :key="item.code" v-for="item in arrNum"> <a-icon slot="icon" type="carry-out" /> <span slot="title" style="color:#333">{{item.name}}</span> <a-tree-node :key="i.code" :title="i.name" v-for="i in item.nodes"> <a-icon slot="icon" type="carry-out" /> <a-tree-node :key="j.code" :title="j.name" v-for="j in i.nodes"> <a-icon slot="icon" type="carry-out" /> </a-tree-node> </a-tree-node> </a-tree-node> </a-tree> </div> <!-- Map --> <div id="container"> </div> </div> </template> <script> import viewMap from '@/components/ZF/viewMap' import { query_station_with_address, query_station_info } from '@/api/factory' export default { name: 'BMapGL', data () { return { showLine: true, total: '', arrNum: [], expanded: [], expandedKeys: [], backupsExpandedKeys: [], autoExpandParent: true, checkedKeys: [], selectedKeys: [], searchStr: '', lng: 118.920079, lat: 32.086119 } }, mounted () { let _this = this this.$nextTick(() => { _this.Address() }) }, watch: { searchStr: { handler (newValue, oldValue) { this.onSearch() }, immediate: true } }, methods: {
// 樹 Address () { this.arrNum = [] this.total = 0 const params = {} query_station_with_address(params).then(res => { if (res.code === '00000') { this.total = res.data.count this.arrNum = res.data.tree this.totalNum() } }) }, //返回其他頁面 onHandleGIS () { this.$parent.handleGIS() this.expandedKeys = [] this.selectedKeys = [] this.autoExpandParent = false this.searchStr = '' },
// input框事件 onSearch () { let vm = this vm.searchValue = vm.searchStr if (vm.searchValue === '') { vm.expandedKeys = [] this.totalNum() this.expandedKeys = [] this.selectedKeys = [] } else { vm.expandedKeys = [] vm.backupsExpandedKeys = [] let candidateKeysList = [] let key = [] candidateKeysList = vm.getkeyList(vm.searchValue, vm.arrNum, []) // 遍歷滿足條件的所有節點 candidateKeysList.map(item => { key = vm.getParentKey(item, vm.arrNum) if (key && !vm.backupsExpandedKeys.some(item => item === key)) { vm.backupsExpandedKeys.push(key) } }) let length = this.backupsExpandedKeys.length for (let i = 0; i < length; i++) { vm.getAllParentKey(vm.backupsExpandedKeys[i], vm.arrNum) } // console.log(candidateKeysList) vm.expandedKeys = vm.backupsExpandedKeys.slice() vm.selectedKeys = vm.backupsExpandedKeys.slice() vm.onSelect(candidateKeysList) //選中樹事件 } }, // 獲取節點中含有value的所有key集合 getkeyList (value, tree, keyList) { // 遍歷所有同一級的樹 for (let i = 0; i < tree.length; i++) { let node = tree[i] // console.log(node.name) // 如果該節點存在value值則push if (node.name.indexOf(value) > -1) { keyList.push(node.code) // console.log(node.code) } // 如果擁有孩子繼續遍歷 if (node.nodes) { this.getkeyList(value, node.nodes, keyList) } } // 因為是引用類型,所有每次遞歸操作的都是同一個數組 return keyList }, // 該遞歸主要用於獲取key的父親節點的key值 getParentKey (key, tree) { let parentKey, temp // 遍歷同級節點 for (let i = 0; i < tree.length; i++) { const node = tree[i] if (node.nodes) { // 如果該節點的孩子中存在該key值,則該節點就是我們要找的父親節點 // 如果不存在,繼續遍歷其子節點 if (node.nodes.some(item => item.code === key)) { parentKey = node.code // eslint-disable-next-line no-cond-assign } else if (temp = this.getParentKey(key, node.nodes)) { // parentKey = this.getParentKey(key,node.children) // 改進,避免二次遍歷 parentKey = temp } } } return parentKey }, // 獲取該節點的所有祖先節點 getAllParentKey (key, tree) { var parentKey if (key) { // 獲得父親節點 parentKey = this.getParentKey(key, tree) // 如果父親節點存在,判斷是否已經存在於展開列表里,不存在就進行push if (parentKey) { if (!this.backupsExpandedKeys.some(item => item === parentKey)) { this.backupsExpandedKeys.push(parentKey) } // 繼續向上查找祖先節點 this.getAllParentKey(parentKey, tree) } } }, // 初始化 initMap (numPoint) { // eslint-disable-next-line new-cap ksMap = new viewMap(numPoint) //實例化class類 }, onExpand (expandedKeys) { // console.log(expandedKeys) this.expandedKeys = expandedKeys this.autoExpandParent = false }, // 樹選中事件 onSelect (selectedKeys, info) { this.arrNum.map(item => { item.nodes.map(i => { i.nodes.map(j => { if (j.data.uniq === selectedKeys[0]) { this.handleEdit(selectedKeys[0], j.data.longitude, j.data.attitude) this.selectedKeys = selectedKeys // this.searchStr = j.name } }) }) }) }, // 初始化點位值 totalNum () { let numPoint = [] this.arrNum.map(item => { item.nodes.map(i => { i.nodes.map(j => { numPoint.push({ uniq: j.data.uniq, lng: j.data.longitude, lat: j.data.attitude, name: j.name }) }) }) }) this.initMap(numPoint) }, // 詳情 handleEdit (selectedKeys, lng, lat) { let modalList = [] const params = { station_uniq: selectedKeys } query_station_info(params).then(res => { if (res.code === '00000') { modalList = res.data ksMap.theLocation(lng, lat, modalList) } }) } } } </script> <style scoped lang="less"> /deep/.BMap_bubble_pop{ padding: 0!important; } /deep/.BMap_bubble_title{ padding-left: 10px; background: #F3F3F3; font-size: 16px; } .show{ display: block; } .block{ display: none; } #container { overflow: hidden; width: 100%; height: 75vh; margin: 0; font-family: "微軟雅黑"; } .GIS_box { position: relative; width: 100%; height: 72vh; .GIS_Button { z-index: 999; position: absolute; top: 10px; right: 10px; } .GIS_Button_left{ width: 250px; padding: 10px; height: 74.9vh; overflow-y:scroll; background: rgba(255, 255, 255, 1); z-index: 999; position: absolute; top: 0px; left: 0px; box-shadow: 3px 3px rgba(235, 235, 235,0.7); } } /deep/.BMap_cpyCtrl span { display: none!important; } /deep/.ant-tree.ant-tree-show-line li span.ant-tree-switcher { color: rgba(0, 157, 255, 1); background: rgba(0, 0, 0, 0); } /deep/.ant-tree-title{ color: #333; } // 經過 // /deep/.ant-tree li .ant-tree-node-content-wrapper:hover { // background: rgba(0, 0, 0, 0); // } // /deep/.ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected { // background-color: rgba(0, 157, 255, 1); // } /deep/.ant-input{ background: rgba(0, 0, 0, 0); color: #333; } </style>
import { query_station_info } from '@/api/factory' //接口 export default class viewMap { constructor (numPoint, zoom) { this.numPoint = numPoint this.zoom = zoom this.map = new BMapGL.Map('container') this.initMap() } initMap () { let point = new BMapGL.Point(105.291, 37.094) //全國中心位置 this.map.centerAndZoom(point, 5) this.map.enableScrollWheelZoom(true) this.onNumPoint() // 創建添加點標記 // let marker = new BMapGL.Marker(point) // this.map.addOverlay(marker) // this.theLocation(118.920079, 32.086119, []) // 詳情窗口 } // 初始化所有點位 onNumPoint () { const vm = this // eslint-disable-next-line no-array-constructor let point = new Array()// 定義數組標注經緯信息 for (let i = 0; i < vm.numPoint.length; i++) { // 遍歷 point[i] = new BMapGL.Point(vm.numPoint[i].lng, vm.numPoint[i].lat) let marker = new BMapGL.Marker(point[i])// 坐標添加到Marker中 vm.map.addOverlay(marker) // marker.setLabel(new BMapGL.Label(vm.numPoint[i].name)) this.infoUniq(marker, vm.numPoint[i].uniq, point[i]) // marker添加點擊事件 // marker.addEventListener('click', function (e) { // // console.log(point[i]) // // let lng = Number(e.latLng.lng.toFixed(6)) // // let lat = Number(e.latLng.lat.toFixed(6)) // // vm.infoUniq(lng, lat) // }) } } // 初始化加載所有彈框點位信息 infoWin (marker, modalList) { let vm = this // 創建圖文信息窗口 let sContent = this.htmlView(modalList) let A = '' A = modalList.cname ? modalList.cname : '--' let opts = { title: A, // 信息窗口標題 message: '' } let infoWindow = new BMapGL.InfoWindow(sContent, opts) marker.addEventListener('click', function () { this.openInfoWindow(infoWindow) }) } // 初始化彈框 infoUniq (marker, uniq) { let modalList = [] const params = { station_uniq: uniq } query_station_info(params).then(res => { if (res.code === '00000') { modalList = res.data // 創建圖文信息窗口 this.infoWin(marker, modalList) } }) } // 點擊用經緯度設置地圖中心點 theLocation (lng, lat, modalList) { let vm = this let zoom = 14 // this.map.clearOverlays() // 清空覆蓋物 let new_point = new BMapGL.Point(lng, lat) this.map.centerAndZoom(new_point, zoom) // 中心點 展示級別 this.map.enableScrollWheelZoom(true) // 注釋。如果點擊再創建標注就會出現點擊點位無法顯示堂框 // let marker = new BMapGL.Marker(new_point) // 創建標注 // this.map.addOverlay(marker) // 將標注添加到地圖中 this.map.panTo(new_point) // 地圖中心顯示 this.infoWins(new_point, modalList) // 詳情窗口 } // 點擊自動顯示彈框 infoWins (new_point, modalList) { // 創建圖文信息窗口 let sContent = this.htmlView(modalList) let A = '' A = modalList.cname ? modalList.cname : '--' let opts = { title: A, // 信息窗口標題 message: '' } let infoWindow = new BMapGL.InfoWindow(sContent, opts) this.map.openInfoWindow(infoWindow, new_point) } // 自定義Dom htmlView (modalList) { return ` <div style="width:560px;padding-left:15px;margin-top:10px"> <div style="overflow: hidden;width:100%"> <div style="float:left;width:50%"> <p> <span class="box_left">廠站狀態 :</span> <span style="display: inline-block;"> <img style="width: 15px;height:15px; margin-right: 5px; margin-bottom: 2px;" src="${modalList.status ? (modalList.status === 's' ? '/static/img/map/xh.png' : '/static/img/map/xh2.png') : ''}" alt="" /> ${modalList.status ? (modalList.status === 's' ? '已入網' : '未入網') : '--'} </span> </p> <p> <span class="box_left">處水能力 :</span> <span>${ modalList.capacity ? modalList.capacity + '噸/天' : '--' } </span> </p> <p> <span class="box_left">工藝介紹 :</span> <span>${ modalList.description ? modalList.description : '--' }</span> </p> <p> <span class="box_left">水質標准 :</span> <span>${ modalList.water_standard ? modalList.water_standard : '--' }</span> </p> <p> <span class="box_left">工藝標准 :</span> <span>${ modalList.technology_standard ? modalList.technology_standard : '--' }</span> </p> </div> <div style="float:left;width:50%""> <p> <span class="box_left">項目周期 :</span> <span>${ modalList.op_stime ? modalList.op_stime : '--' } - ${ modalList.op_etime ? modalList.op_etime : '--' }</span> </p> <p> <span class="box_left">項目地址 :</span> <span style="overflow: hidden;text-overflow: ellipsis; white-space: nowrap;">${ modalList.address ? modalList.address : '--' }</span> </p> </div> </div> </div> ` } }