<template> <div> <div id="map" class="leaflet_container" style="background-color: white"> <div class="right-card" style="right: 150px;width: 200px"> <el-button style="height: 40px;width: 40px;padding: 0px" @click="drawSquare"> <img src="@/assets/global_images/square.png" style="height: 18px;width: 18px;"> </el-button> <el-button style="height: 40px;width: 40px;padding: 0px" @click="drawPolygon"> <img src="@/assets/global_images/polygon.png" style="height: 18px;width: 18px;"> </el-button> <el-button style="height: 40px;width: 40px;padding: 0px" @click="drawDelete"> <img src="@/assets/global_images/delete.png" style="height: 18px;width: 18px;"> </el-button> </div> <div class="right-card"> <el-row> <el-button icon="el-icon-copy-document" style="width: 100px;" @click="btnList=!btnList"> 图层<i class="el-icon-arrow-down el-icon--right"/></el-button> </el-row> <el-checkbox-group v-show="btnList" v-model="selectParts" style=" width: 130px;margin-top: 10px;position: absolute;right: 10px"> <el-checkbox key="底图" label="底图" border style="margin-left: 10px;width: 130px;background-color: white" @change="mapChange"/> <el-checkbox v-for="parts in partsOptions" :label="parts" :key="parts" border style="width: 130px;background-color: white" @change="partsChange">{{ parts }}</el-checkbox> </el-checkbox-group> </div> <div style="margin-top: 20px;position: absolute;left:50px;z-index: 100000"> <el-input v-model="keyword" placeholder="请输入查询条件" class="input-with-select" style="width: 300px;"> <el-button slot="append" icon="el-icon-search" style="background-color: #409eff;color: white" @click="search"/> </el-input> <div v-show="isShow" class="search-total"> 共找到 {{ searchlist.length }} 条个查询结果 </div> <div v-show="isShow && searchlist.length!==0" class="table"> <el-table :data="showlist" :show-header="false" style="border-color: white"> <el-table-column key="编码" label="编码" width="298" align="left" show-overflow-tooltip> <template slot-scope="scope"> <el-row class="table-item"> <el-col :span="2"> <div class="item-icon"> {{ scope.$index + 1 }}</div> </el-col> <el-col :offset="2" :span="8" style="font-size: 12px;"> <el-row style="height: 18px">名称:{{ scope.row.小类名称 }}</el-row> <el-row style="height: 18px">编码:{{ scope.row.编码 }}</el-row> <el-row style="height: 18px;margin-bottom: 3px">地址:{{ scope.row.编码 }}</el-row> </el-col> </el-row> </template> </el-table-column> </el-table> <el-pagination style="background-color: white" :current-page="offset" :page-size="5" :total="searchlist.length" align="center" layout="prev, pager, next" @current-change="handleCurrentChange"/> </div> </div> </div> </div> </template> <script> import L from 'leaflet' import 'leaflet/dist/leaflet.css' import { getServerList } from '@/api/server' var esri = require('esri-leaflet') const rainHole = [14] const sewageHole = [37] const video = [35] const lamp = [1, 3, 4, 22, 25, 34] const toilet = [12, 13] const garbage = [24] const othersParts = [2, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 23, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 38, 39, 40] export default { name: 'MapSearch', data() { return { drawLayer: null, keyword: '', offset: 1, btnList: false, listLoading: false, // 加载动画 TianDiTu: { Normal: { Map: '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', Annotion: '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' }, Satellite: { Map: 'https://t{s}.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8', Annotion: 'https://t{s}.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8' }, Terrain: { Map: 'https://t{s}.tianditu.gov.cn/ter_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ter&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8', Annotion: 'https://t{s}.tianditu.gov.cn/cta_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cta&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8' }, Subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'] }, map: null, showtable: true, isShow: false, partsOptions: ['网格', '商户', '视频监控点', '路灯杆和灯箱', '雨水井盖', '污水井盖', '公共厕所', '垃圾箱', '其他部件'], selectParts: ['底图', '网格', '商户', '视频监控点', '路灯杆和灯箱', '雨水井盖', '污水井盖', '公共厕所', '垃圾箱', '其他部件'], showlist: [], searchlist: [ { 编码: 11111, 小类名称: '视频监控点', 地址: '江西省福州市' }, { 编码: 22222, 小类名称: '视频监控点', 地址: '江西省福州市' }, { 编码: 3333, 小类名称: '视频监控点', 地址: '江西省福州市' }, { 编码: 4444, 小类名称: '视频监控点', 地址: '江西省福州市' }, { 编码: 55555, 小类名称: '视频监控点', 地址: '江西省福州市' }, { 编码: 666, 小类名称: '视频监控点', 地址: '江西省福州市' }, { 编码: 777, 小类名称: '视频监控点', 地址: '江西省福州市' }, { 编码: 888, 小类名称: '视频监控点', 地址: '江西省福州市' }, { 编码: 999, 小类名称: '视频监控点', 地址: '江西省福州市' }, { 编码: 11111, 小类名称: '视频监控点', 地址: '江西省福州市' }, { 编码: 2222, 小类名称: '雨水井盖', 地址: '海淀区' }], listQuery: { offset: 1, limit: 15 }, // 筛选条件 list: [], maps: [], parts: [], baseUrl: '', partsUrl: '', mapUrl: '', multipleSelection: [], // 多选选中项 iconlist: [], baselayer: [], caselist: [], // 路灯(map) statisticNum: { work: 0, todayCase: 0, allCase: 0, merchant: 0, parts: 0 }, status: { register: 0, dispatch: 0, disposal: 0, disposaling: 0 } } }, destroyed() { window.removeEventListener('click', this.handleKeyup, true) this.socket.close() }, mounted() { window.addEventListener('click', this.handleKeyup, true) this.init() }, methods: { handleKeyup(val) { if (this.btnList && val.target.id === 'map') { this.btnList = false } }, search() { this.offset = 1 this.showlist = this.searchlist.slice(0, 5) this.isShow = true }, drawDelete() { if (this.drawLayer) { this.drawLayer.layer.remove() } }, drawSquare() { if (this.drawLayer) { this.drawLayer.layer.remove() } this.$nextTick(() => { this.map.pm.enableDraw('Rectangle', { snappable: false }) }) }, drawPolygon() { if (this.drawLayer) { this.drawLayer.layer.remove() } this.$nextTick(() => { this.map.pm.enableDraw('Polygon', { snappable: false }) }) }, mapChange(val) { if (!val) { // 隐藏底图 for (let i = 0; i < this.maps.length; i++) { this.map.removeLayer(this.maps[i]) } } else { for (let i = 0; i < this.maps.length; i++) { this.map.addLayer(this.maps[i]) } } }, partsChange(val, item) { console.log(val, item.target.defaultValue) var selectItem switch (item.target.defaultValue) { case '视频监控点': selectItem = video break case '路灯杆和灯箱': selectItem = lamp break case '公共厕所': selectItem = toilet break case '垃圾箱': selectItem = garbage break case '雨水井盖': selectItem = rainHole break case '污水井盖': selectItem = sewageHole break case '其他部件': selectItem = othersParts break default: selectItem = [] break } if (!val) { // 隐藏底图 for (let i = 0; i < selectItem.length; i++) { this.map.removeLayer(this.parts[selectItem[i] - 1]) } } else { for (let i = 0; i < selectItem.length; i++) { this.map.addLayer(this.parts[selectItem[i] - 1]) } } }, tableclick() { this.showtable = !this.showtable }, removemarkers() { for (var i = 0; i < this.iconlist.length; i++) { this.map.removeLayer(this.iconlist[i]) } var base = this.baselayer this.map.eachLayer(function(layer) { if (layer !== base[0] && layer !== base[1]) { layer.remove() } }) }, setZoom(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', '5000000']// 级别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) { return 18 - i + 2 // 之所以会多2,是因为地图范围常常是比例尺距离的10倍以上。所以级别会增加3。 } } return 5 }, async init() { const map = L.map('map', { minZoom: 2, // maxZoom: 18, center: [27.755, 116.08], zoom: 18, zoomControl: false, attributionControl: false, crs: L.CRS.EPSG3857 }) map.doubleClickZoom.disable() this.map = map // data上需要挂载 window.map = map // this.baselayer.push(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)) // this.baselayer.push(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)) var that = this this.map.on('pm:create', e => { if (that.drawLayer) { that.drawLayer.layer.remove() } that.drawLayer = e }) const res = await getServerList(this.listQuery) this.list = res.data.rows for (var i = 0; i < this.list.length; i++) { if (this.list[i].name === 'GIS地图') { this.baseUrl = this.list[i].url } else if (this.list[i].name === '部件分层URL') { this.partsUrl = this.list[i].url } else if (this.list[i].name === '二维地图URL') { this.mapUrl = this.list[i].url } } // 底图 for (i = 0; i <= 21; i++) { var item = { url: this.baseUrl + this.mapUrl + '/' + i.toString() } this.maps.push(esri.featureLayer(item).addTo(map)) } // 部件 for (i = 1; i <= 40; i++) { item = { url: this.baseUrl + this.partsUrl + '/' + i.toString(), minZoom: 18 } if (i === 15) { item = { url: this.baseUrl + this.partsUrl + '/' + i.toString(), minZoom: 18, style: function(feature) { return { color: '#ff0000', opacity: 0.75, weight: 5 } } } } var layer = esri.featureLayer(item).addTo(map) layer.on('click', function(e) { console.log(e) console.log(e.layer.feature.properties) var str = '<div style="font-size: 14px;width:200px;">' + '<div style="font-size: 14px;margin-bottom: 8px;">' + '<div>' + e.layer.feature.properties.小类名称 + '</div></div>' + '<div style="padding-bottom: 4px"><col style="padding-right: 5px">大类:</col>' + e.layer.feature.properties.大类名称 + '</div>' + '<div style="padding-bottom: 4px"><col style="padding-right: 5px">小类:</col>' + e.layer.feature.properties.小类名称 + '</div>' + '<div style="padding-bottom: 4px"><col style="padding-right: 5px">部件编码:</col>' + e.layer.feature.properties.编码 + '</div>' + '<div style="padding-bottom: 4px"><col style="padding-right: 5px">权属单位:</col>' + e.layer.feature.properties.权属单位 + '</div>' + '<div style="padding-bottom: 4px"><col style="padding-right: 5px">详细地址:</col>' + e.layer.feature.properties.详细地址 + '</div>' + '<div>' var popup = L.popup().setContent(str) e.layer.dragging._marker.bindPopup(popup, { minWidth: 200 }).openPopup() // var id = e.layer.feature.properties.FID }) this.parts.push(layer) } this.map.setZoom(15) }, handleCurrentChange(val) { console.log(val, this.searchlist) this.offset = val var num = 5 * val >= this.searchlist.length ? this.searchlist.length : 5 * val this.showlist = this.searchlist.slice(5 * (val - 1), num) } } } </script> <style rel="stylesheet/scss" lang="scss" scoped> /deep/ .el-input-group__append, .el-input-group__prepend { background-color: #409eff !important; border: 1px solid #409eff !important; } /*/deep/ .leaflet-touch .leaflet-control-layers, /deep/ .leaflet-touch .leaflet-bar {*/ /*!*border: 2px solid rgba(0,0,0,0.2);*!*/ /*!*background-clip: padding-box;*!*/ /*position: absolute !important;*/ /*right: 300px !important;*/ /*top: 10px;*/ /*}*/ $tableTitleHeight:35px; .leaflet_container{ width: 100%; height: 85vh; } .search-total{ background-color: white; width: 300px;height: 35px; margin-top: 10px;border: 1px solid #DCDFE6; padding-left: 15px;color: #409eff; padding-top: 8px; font-size: 13px; border-radius:3px; } .draw-icon{ background-color: white; width: 100px;height: 40px; border: 1px solid #DCDFE6; border-radius:4px; } .table{ width: 300px;margin-top: 3px; border: 1px solid #DCDFE6; border-radius:3px; /deep/ .el-table th.is-leaf, /deep/ .el-table td { border-bottom: 1px solid white !important; } /deep/ .el-table--group::after, .el-table--border::after, .el-table::before { background-color: white !important; } .table-item{ padding: 5px; margin-top: 2px; margin-bottom: 1px; -moz-box-shadow: 0px 1px 3px #d9d9d9; /* 老的 Firefox */ box-shadow: 0px 1px 3px #d9d9d9; .item-icon{ width: 30px; height: 30px; background-size: contain; background-image: url("../../assets/global_images/point.png"); color: white; text-align: center; margin-top: 10px; margin-left: 5px; padding-top: 2px; } } } .top_title{ height: 40px; font-size: 18px; border: 1px solid #b5b5b5; padding-top: 10px; } .title{ height: 40px; width: 320px; padding-top: 10px; padding-left: 5px; z-index: 100000; background-color: rgba(255, 255, 255, 0.91); } .titletext{ text-align: center; font-size: 15px; } .titlenumtext{ text-align: center; font-size: 19px; } .list{ text-align:center; width: 500px; height: 40px; z-index: 10000; position: absolute; right:20px; top:20px; } .btn_bottom{ text-align:center; width: 100%; height:70px; z-index: 1000; position: fixed; bottom: 0; left: 0;right:0; } .table-name{ position:relative; width: 100px; top:20px; margin:-10px auto; //外面的div高度的一半 z-index: 100001; } .right-card{ margin-top: 20px;position: absolute;right:50px;z-index: 100000;width: 130px; } .table-title{ background-color:rgba(243, 243, 243, 1); height: $tableTitleHeight; .title-header{ line-height:$tableTitleHeight; color: #606266; font-size: 15px; i{ margin-left: 5px; margin-right: 5px; } } } </style>