<template> <div style="margin-top: -10px"> <el-row :gutter="20"> <div v-show="showpoi"> <el-col :span="3"> <el-input v-model="keywords" size="small" type="text" placeholder="兴趣点关键字" clearable /> </el-col> <el-col :span="5"> <el-button type="primary" size="small" @click="queryOnMap">查询</el-button> <el-button type="info" size="small" @click="clearMap"> 清除地图 </el-button> </el-col> </div> <el-col :span="6" :offset="8" style="text-align: right;"> <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 v-show="showpoi" label="2">兴趣点属性</el-radio-button> </el-radio-group> </el-col> <el-col v-if="queryEventSwitch === '0'" :span="10" :offset="0" style="text-align: right;"> <el-select v-model="form.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="10" :offset="0" style="text-align: right;"> <el-button type="primary" size="small" @click="checkEventPoint"> 事件提交 </el-button> </el-col> </el-row> <div id="map" ref="mapDiv" class="baseMap"/> </div> </template> <script> import L from 'leaflet' import 'leaflet/dist/leaflet.css' import { mapConfig, serverConfig } from './ArcGISConfig' const esri = require('esri-leaflet') export default { name: 'LeafletMap', data() { return { map: null, markers: [], layers: { bjPoint: '', // 部件点图层 grid: '' // 单元网格图层 }, form: { longitude: '', // 定位点经度 latitude: '', // 定位点纬度 communityId: '', // 社区ID communityName: '', // 社区名称 gridId: '', // 单元网格ID componentId: '', // 部件ID componentName: '' // 部件名称 }, // 主页面返回值 showpoi: false, keywords: '', // 查询关键字 showEventPointPopup: true, // 是否显示事部件的popup queryEventSwitch: '1', // 1==查询事件;0==查询部件 compListOpts: [] // 部件选择下拉框option } }, mounted() { this.initMap() }, methods: { initMap() { const map = L.map('map', { minZoom: 13, // maxZoom: 18, center: [27.755, 116.08], zoom: 16, zoomControl: false, attributionControl: false, crs: L.CRS.EPSG3857 }) map.doubleClickZoom.disable() this.map = map // data上需要挂载 window.map = map esri.dynamicMapLayer({ url: serverConfig.mapUrlBase }).addTo(map) this.addLayers() const that = this map.on('click', function(e) { console.log('e', e) console.log('e.latlng', e.latlng) console.log('queryEventSwitch', that.queryEventSwitch) that.clearPoints() // 加载定位点 if (that.showEventPointPopup) { const icon = L.icon({ iconUrl: require('../../assets/icons/icon-position.png'), iconSize: [35, 35] }) const pos = L.marker(e.latlng, { icon: icon }) that.markers.push(pos) that.map.addLayer(pos) // 查询事件或者部件 if (that.queryEventSwitch === '1') { // 事件定位 // 1查询底图得到所在网格与所在社区 const query = that.layers.grid.query() query.nearby(e.latlng, 10) query.run(function(error, featureCollection, response) { if (error) { console.log(error) return } const result = featureCollection.features[0].properties // 赋值 that.form.longitude = e.latlng.lng that.form.latitude = e.latlng.lat that.form.gridId = result.CommuId that.form.communityId = result.CommuId that.form.communityName = result.CommuName pos.bindPopup('坐标:[' + that.form.longitude.toFixed(4) + ', ' + that.form.latitude.toFixed(4) + ']' + '<p>' + '所在社区:' + result.CommuName).openPopup() }) } else if (that.queryEventSwitch === '0') { var latlngs = [] var p1 = that.getLonAndLat(e.latlng.lng, e.latlng.lat, 0, 2.5) latlngs.push([p1.lat, p1.lon]) var p2 = that.getLonAndLat(e.latlng.lng, e.latlng.lat, 90, 2.5) latlngs.push([p2.lat, p2.lon]) var p3 = that.getLonAndLat(e.latlng.lng, e.latlng.lat, 180, 2.5) latlngs.push([p3.lat, p3.lon]) var p4 = that.getLonAndLat(e.latlng.lng, e.latlng.lat, 270, 2.5) latlngs.push([p4.lat, p4.lon]) var polyline = L.polygon(latlngs) const bjQuery = that.layers.bjPoint.query() bjQuery.within(polyline) bjQuery.run(function(error, featureCollection, response) { if (error) { console.log(error) return } if (featureCollection.features.length > 0) { const result = featureCollection.features console.log(result) // 赋值 that.compListOpts = [] let content = '' result.forEach((item, index) => { content += '<p>部件' + (index + 1) + ':' + item.properties.大类名称 + '-' + item.properties.小类名称 + '-' + item.properties.编码 const comp = {} comp.name = '部件' + (index + 1) + ':' + item.properties.大类名称 + '-' + item.properties.小类名称 + '-' + item.properties.编码 comp.value = item.properties.编码 that.compListOpts.push(comp) }) pos.bindPopup('坐标:[' + e.latlng.lng.toFixed(4) + ', ' + e.latlng.lat.toFixed(4) + '],附近5米的部件有:' + content).openPopup() const query = that.layers.grid.query() query.nearby(e.latlng, 10) query.run(function(error, featureCollection, response) { if (error) { console.log(error) return } const result = featureCollection.features[0].properties // 赋值 that.form.longitude = e.latlng.lng that.form.latitude = e.latlng.lat that.form.gridId = result.CommuId that.form.communityId = result.CommuId that.form.communityName = result.CommuName }) } else { that.$message({ message: '没有查询到部件,请重新定位', type: 'warning' }) } } ) } } }) }, addLayers() { this.layers.bjPoint = esri.featureLayer({ url: serverConfig.mapUrlBj + '/0' }) this.layers.grid = esri.featureLayer({ url: serverConfig.mapUrlBase + '/16' }) this.map.addLayer(this.layers.bjPoint) this.map.addLayer(this.layers.grid) }, switchEventOrComponent: function() { // 如果选中的是事件定位(1)或部件定位(0),点击地图时弹出事件或者部件的popup;否则(2以上)显示兴趣点结果的属性popup this.showEventPointPopup = this.queryEventSwitch < 2 this.clearPoints() }, clearPoints() { const that = this this.markers.forEach(marker => { that.map.removeLayer(marker) }) }, // 返回事件定位的结果 checkEventPoint: function() { this.$emit( 'closeMapQueryDialogByEvent', this.form.longitude, this.form.latitude, this.form.communityId, this.form.communityName, this.form.gridId) this.clearMap() }, // 返回部件定位的结果 checkComponentPoint: function() { this.$emit( 'closeMapQueryDialogByComp', this.form.longitude, this.form.latitude, this.form.communityId, this.form.communityName, this.form.gridId, this.form.componentId) this.clearMap() }, clearMap() { this.clearPoints() // 清除data属性值 this.keywords = '' this.showEventPointPopup = true // 是否显示事部件的popup this.queryEventSwitch = '1' // 1==查询事件;0==查询部件 this.compListOpts = [] // 部件选择下拉框option this.form.longitude = '' // 定位点经度 this.form.latitude = '' // 定位点纬度 this.form.communityId = '' // 社区ID this.form.communityName = '' // 社区名称 this.form.gridId = '' // 单元网格ID this.form.componentId = '' // 部件ID this.form.componentName = '' // 部件名称 }, numberToRadius(t) { return (t * Math.PI) / 180 }, numberToDegree(t) { return (180 * t) / Math.PI }, /** * 根据一个经纬度及距离角度,算出另外一个经纬度 * @param {*} lon 经度 113.3960698 * @param {*} lat 纬度 22.941386 * @param {*} brng 方位角 45 ---- 正北方:000°或360° 正东方:090° 正南方:180° 正西方:270° * @param {*} dist 90000距离(米) */ getLonAndLat(lon, lat, brng, dist) { // 大地坐标系资料WGS-84 长半径a=6378137 短半径b=6356752.3142 扁率f=1/298.2572236 var a = 6378137 var b = 6356752.3142 var f = 1 / 298.257223563 var lon1 = lon * 1 var lat1 = lat * 1 var s = dist var alpha1 = this.numberToRadius(brng) var sinAlpha1 = Math.sin(alpha1) var cosAlpha1 = Math.cos(alpha1) var tanU1 = (1 - f) * Math.tan(this.numberToRadius(lat1)) var cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1 var sigma1 = Math.atan2(tanU1, cosAlpha1) var sinAlpha = cosU1 * sinAlpha1 var cosSqAlpha = 1 - sinAlpha * sinAlpha var uSq = cosSqAlpha * (a * a - b * b) / (b * b) var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))) var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))) var sigma = s / (b * A), sigmaP = 2 * Math.PI while (Math.abs(sigma - sigmaP) > 1e-12) { var cos2SigmaM = Math.cos(2 * sigma1 + sigma) var sinSigma = Math.sin(sigma) var cosSigma = Math.cos(sigma) var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))) sigmaP = sigma sigma = s / (b * A) + deltaSigma } var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1 var lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1, (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp)) var lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1) var C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)) var L = lambda - (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))) var revAz = Math.atan2(sinAlpha, -tmp) // final bearing var lonLatObj = { lon: lon1 + this.numberToDegree(L), lat: this.numberToDegree(lat2) } return lonLatObj } } } </script> <style scoped> @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; } .leaflet-container { background: #fff0; } </style>