<template> <div> <div class="overview-map-container"> <!--地图--> <a-map-container ref="map" :center="center" :zoom="zoom" :base-layer="baseLayer" :style="{height:(bodyHeight-70)+'px'}" vid="overview" class="map-demo" @ready="mapReady" > <!--搜索结果点标注--> <a-map-marker v-for="(marker,index) of searchMarkers" :key="index" :position="marker.lnglat" > <div class="search-marker" :style="{'width':searchResultSize[0]+'px','height':searchResultSize[1]+'px'}" @click="openInfoWindow(marker.id, marker.lnglat, searchResultOffset[1])" @contextmenu.prevent="moveInfoShow(marker.id, marker.lnglat, searchResultOffset[1])" > <el-image :src="searchResultIcon" class="search-marker-image" fit="fill" /> <div class="search-marker-label"> {{ index+1 }} </div> </div> </a-map-marker> </a-map-container> <!--搜索框--> <map-search-comp :list="resultList" placeholder="井编号/名称/位置" @search="search" @change-page="searchPageChange" @click-item="searchItemClick" @clear="clearSearch" /> </div> <!--鼠标右键点击菜单窗口--> <popup-layer-choose :show="layerWindowShow" @close="closePopupLay" @click-menu="clickMenu" /> <!-- 位置纠偏功能窗口 --> <popupLocation ref="popupLocation" :lonlatpopup="lonLatPopup" :show="locationWindowShow" @close="closePopupLocation" /> </div> </template> <script> import Vue from 'vue' import { mapGetters } from 'vuex' import AMapContainer from '@/components/Amap/AMapContainer' import AMapMarker from '@/components/Amap/AMapMarker' import MapSearchComp from '@/views/wellManage/components/mapSearchComp' import { getWellList, getWellInfo } from '@/api/overview/wellOverview' import { toPixel, toSize, toLngLat } from '@/components/Amap/utils/convert-helper' import WellInfoWindow from './components/infoWindowWell' import AMapLoader from '@amap/amap-jsapi-loader' import popupLayerChoose from '@/views/wellManage/components/popupLayerChoose' import popupLocation from '@/views/wellManage/components/popupLocation' export default { name: 'PostionCorrectWell', components: { AMapContainer, AMapMarker, MapSearchComp, popupLayerChoose, popupLocation }, data() { return { map: null, // 地图对象 baseLayer: 'gaode_vec', // 底图图层 center: [this.$store.getters.lng, this.$store.getters.lat], // 地图中心 zoom: 12, // 地图缩放比例 searchMarkers: [], // 当前搜索页展示marker集合 resultList: [], // 搜索结果列表 markers: [], // 所有井的点原始数据 searchResultSize: [24, 30], searchResultIcon: require('@/assets/overview/pure-position-icon.png'), // 报警图标 searchResultOffset: [-12, -30], massMarks: null, // 海量点对象 layerWindowShow: false, // 图层选择窗口显示 locationWindowShow: false, // 位置纠偏窗口显示 locationCoordinates: [], locationMarker: '', lonLatPopup: [], locationWellId: '', postionForm: { longitude: '', // 经度 latitude: '', // 纬度 postion: '', // 详细地址 postionlatlon: '' } } }, computed: { ...mapGetters([ 'needRefresh', 'bodyHeight' ]) }, watch: { postionlatlon(val) { var that = this window._AMapSecurityConfig = { securityJsCode: this.$store.getters.amapSecurityCode } AMapLoader.load({ key: this.$store.getters.amapKey // 秘钥,从store中取 }).then((AMap) => { AMap.plugin('AMap.Geocoder', function() { var geocoder = new AMap.Geocoder({ city: '' }) var lnglat = val.split(',') geocoder.getAddress(lnglat, function(status, result) { if (status === 'complete' && result.info === 'OK') { that.postionForm.postion = result.regeocode.formattedAddress } }) }) }) } }, methods: { // 初始化放这里 mapReady(map) { this.map = map var that = this this.fetchWellList() // 加载全部井 map.on('click', function(e) { console.log(e) that.postionForm.longitude = e.lnglat.lng that.postionForm.latitude = e.lnglat.lat that.postionForm.postionlatlon = e.lnglat.lng + ',' + e.lnglat.lat }) }, clickMenu() { this.lonLatPopup = this.locationCoordinates this.$refs.popupLocation.setQuery(this.lonLatPopup) this.clearInfoWindow() this.clearSearch() this.layerWindowShow = false this.locationWindowShow = true const { searchResultIcon, searchResultSize } = this const icon = new window.AMap.Icon({ size: toSize(searchResultSize), // 图标尺寸 image: searchResultIcon, // Icon的图像 imageSize: toSize(searchResultSize) // 根据所设置的大小拉伸或压缩图片 }) this.locationMarker = new window.AMap.Marker({ icon: icon, position: this.locationCoordinates, draggable: true, cursor: 'move' }) this.locationMarker.setMap(this.map) this.locationMarker.on('dragend', e => { this.lonLatPopup[0] = e.lnglat.lng this.lonLatPopup[1] = e.lnglat.lat this.$refs.popupLocation.setQuery(this.lonLatPopup) }) }, closePopupLay() { this.clearInfoWindow() this.clearSearch() this.layerWindowShow = false this.fetchWellList() }, closePopupLocation() { const { map } = this map.remove(this.locationMarker) this.locationWindowShow = false this.fetchWellList() setTimeout(() => { this.moveInfoShow(this.locationWellId, this.locationCoordinates) }, 200) }, // 数据查询 search(keywords) { if (keywords === '') { this.$message.warning('搜索条件不能为空') } else { this.resultList = this.markers.filter(item => { if (item.wellCode.includes(keywords) || item.wellName.includes(keywords) || item.position.includes(keywords)) { return true } else { return false } }) } }, // 搜索结果页面变化,触发地图展示列表中所有 searchPageChange(currentMarkers) { // 增加查询展示图层 this.searchMarkers = currentMarkers }, // 点击搜索结果项居中,弹窗 searchItemClick(marker) { this.center = marker.lnglat this.openInfoWindow(marker.wellId, marker.lnglat, this.searchResultOffset[1]) }, // 清空查询 clearSearch() { this.searchMarkers = [] this.resultList = [] }, // 过滤海量点,给markers赋visible值 filterMassMarker(listQuery, showMessage = false) { const hideWellIds = []// 要隐藏的井编号 // 2. 整理查询条件 const keywords = listQuery.keywords // 关键字 const wellTypes = listQuery.wellTypes ? listQuery.wellTypes : listQuery.wellType ? [listQuery.wellType] : [] // 井类型 let deptids = [] // 所有权属 if (listQuery.deptid) { deptids = this.fetchDeptList(listQuery.deptid) // 获取所有下级 } // 3.查询全部井,是否匹配,只要有一项不匹配则show为false for (const marker of this.markers) { let show = true // 关键字不为空,且没有匹配成功,不显示, 关键字匹配井编号和位置 if (keywords && keywords !== '' && !(marker.wellCode.indexOf(keywords) !== -1 || marker.position.indexOf(keywords) !== -1)) { show = false } // 部门不为空, 且没有匹配成功,多部门匹配 if (deptids.length > 0 && deptids.indexOf(marker.deptid) === -1) { show = false } // 井类型不为空,且没有匹配成功 if (wellTypes && wellTypes.length > 0 && wellTypes.indexOf(marker.wellType) === -1) { show = false } // 如果show为false,放入需要隐藏的井id列表 if (show === false) { hideWellIds.push(marker.wellId) } else { this.center = marker.lnglat } marker.visible = show } this.resetMassMarker() }, // 重置海量点,根据marker的visible属性,重置海量点图层数据 resetMassMarker() { const { map } = this const markers = this.markers.filter(item => item.visible) // 过滤全部visible为true的显示 if (markers.length === 0) { this.massMarks.clear() } else { this.massMarks.setData(markers) } // 将海量点添加至地图实例 this.massMarks.setMap(map) }, // 加载聚合点 mountClusters() { // 聚合点数据应该是一组包含经纬度信息的数组。lnglat 为经纬度信息字段,weight 字段为可选数据,表示权重值,以权重高的点为中心进行聚合。 var points = this.markers const markers = [] var icon = new window.AMap.Icon({ size: toSize(20, 20), // 图标尺寸 image: 'static/images/well/pin.svg', // Icon的图像 imageSize: toSize(20, 20) // 根据所设置的大小拉伸或压缩图片 }) for (var i = 0; i < points.length; i += 1) { markers.push(new window.AMap.Marker({ position: points[i]['lnglat'], icon: icon, // 添加 Icon 实例 offset: toPixel(-10, 0) })) } }, _renderCluserMarker(context) { console.log(context) const count = this.markers.length const factor = Math.pow(context.count / count, 1 / 18) const div = document.createElement('div') const Hue = 180 - factor * 180 const bgColor = 'hsla(' + Hue + ',100%,50%,0.9)' const fontColor = '#ffffff' const borderColor = 'hsla(' + Hue + ',100%,40%,1)' const shadowColor = 'hsla(' + Hue + ',100%,50%,1)' div.style.backgroundColor = bgColor const size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20) div.style.width = div.style.height = size + 'px' div.style.border = 'solid 1px ' + borderColor div.style.borderRadius = size / 2 + 'px' div.style.boxShadow = '0 0 1px ' + shadowColor div.innerHTML = context.count div.style.lineHeight = size + 'px' div.style.color = fontColor div.style.fontSize = '14px' div.style.textAlign = 'center' context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2)) context.marker.setContent(div) }, // 初始化海量点,并不复制 initMassMarker() { const { map, massMarkerUrl, massMarkerSize, massMarkerOffset } = this this.firstAmount = false // 海量点样式 const style = { url: massMarkerUrl, anchor: toPixel(massMarkerOffset), size: toSize(massMarkerSize) } // 海量点初始化 this.massMarks = new window.AMap.MassMarks([], { zIndex: 5, // 海量点图层叠加的顺序 zooms: [3, 18], // 在指定地图缩放级别范围内展示海量点图层 style: style // 设置样式对象 }) // this.massMarks.setData(this.markers) this.massMarks.setMap(map) // 点击弹窗 this.massMarks.on('click', e => { this.openInfoWindow(e.data.id, e.data.lnglat, -massMarkerOffset[1]) }) console.log('初始化海量点完毕') }, // 获取全部井列表 fetchWellList() { this.loading = true getWellList().then(response => { this.loading = false if (response.code === 200) { const wells = response.data if (wells.length > 0) { this.markers = [] for (const well of wells) { const marker = { ...well, lnglat: [parseFloat(well.lngGaode), parseFloat(well.latGaode)], icon: this.commonIcon, visible: true, wellStatus: 'normal' } this.markers.push(marker) this.searchMarkers = this.markers } if (this.type === 'massMarkers') { this.initMassMarker() // 加载海量点 } else if (this.type === 'cluster' && this.checkedLayer.indexOf('well') > -1) { this.mountClusters() // 加载聚合点 } } } }) }, // 关闭所有弹窗 clearInfoWindow() { const { map } = this map.clearInfoWindow() }, /** * 打开井详情弹窗 * @param wellId 井id * @param coordinates 弹窗位置: [经度,纬度] * @param offsetY 弹窗Y轴偏移,为负值 */ moveInfoShow(wellId, coordinates, offsetY) { this.locationWellId = wellId this.locationCoordinates = coordinates this.locationWindowShow = false this.layerWindowShow = !this.layerWindowShow this.resultList = this.markers.filter(item => { if (item.id === wellId) { return true } else { return false } }) // // 首先获取井详情 // getWellInfo(wellId).then(response => { // console.log(response) // }) }, openInfoWindow(wellId, coordinates, offsetY) { this.clearInfoWindow() // 首先获取井详情 getWellInfo(wellId).then(response => { if (response.code === 200) { const wellInfo = { ...response.data } // 加载弹窗组件 const WellInfo = Vue.extend({ render: h => h(WellInfoWindow, { props: { wellInfo: wellInfo }}) }) const wellWindow = new WellInfo().$mount() const infoWindow = new window.AMap.InfoWindow({ content: wellWindow.$el, // 显示内容 offset: [0, offsetY], // 偏移 autoMove: true // 是否自动调整窗体到视野内 }) infoWindow.open(this.map, new toLngLat(coordinates)) } }) } } } </script> <style rel="stylesheet/scss" lang="scss"> // 查询框 .map-search-div{ position: absolute; z-index: 100; padding: 5px 20px; background-color: rgba(244, 244, 244, 0.9); /*left: 90px;*/ .el-form-item{ margin-bottom: 0px; } } // 刷新框 .function-div{ position: absolute; right: 10px; top: 7px; z-index: 1100; padding: 10px; color: #ce8b74; font-size: 14px; /*background-color: rgba(244, 233, 230, 1.0);*/ .font-red{ color: red; font-weight: bold; } .el-icon-refresh:hover{ color: red; font-weight: bold; cursor: pointer; } } // 刷新框 .refresh-div{ position: absolute; right: 10px; top: 7px; z-index: 100; padding: 10px; color: #ce8b74; font-size: 14px; background-color: rgba(244, 233, 230, 1.0); .font-red{ color: red; font-weight: bold; } .el-icon-refresh:hover{ color: red; font-weight: bold; cursor: pointer; } } // 地图 .overview-map-container{ width: 100%; .map-demo{ width: 100%; .svg-icon{ width: 20px; height: 20px; } .alarm-icon{ width: 29px; height: 30px; } .nomal-info-window{ background-color: pink; } } } .search-marker{ position: relative; .search-marker-image{ width: 100%; height: 100%; } .search-marker-label{ position:absolute; font-size: 14px; font-weight: 600; color:#FFF; z-index:50; top: 4px; left: 50%; transform: translateX(-50%) } } </style>