<template> <app-container id="detailroute"> <el-collapse v-model="activeNames" class="route-coll"> <el-collapse-item title="(一)基本信息" name="1"> <el-form ref="dataForm" :rules="rules" :model="routeForm" label-position="right" label-width="130px" size="small" style="padding-top:20px;padding-right: 40px"> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="路线描述" prop="routeName" > <el-input v-model.trim="routeForm.routeName" :disabled="dialogStatus=='detail'" :placeholder="dialogStatus=='detail'?'':'必填'" type="text"/> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="报警类型" prop="alarmType"> <el-select v-model="routeForm.alarmType" :disabled="dialogStatus=='detail'" :placeholder="dialogStatus=='detail'?'':'必填'" filterable clearable value="" style="width: 100%"> <el-option v-for="item in alarmlist" :key="item.value" :label="item.name" :value="item.value"/> </el-select> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="偏离报警距离(米)" prop="alarmDistance"> <el-input v-model.trim="routeForm.alarmDistance" :disabled="dialogStatus=='detail'" :placeholder="dialogStatus=='detail'?'':'必填'" type="text" oninput="value=value.replace(/^\.+|[^\d.]/g,'')"/> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="起点地址"> <el-input v-model.trim="routeForm.startAddress" :disabled="dialogStatus=='detail'" :placeholder="dialogStatus=='detail'?'':'起点地址'" type="text"/> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="终点地址"> <el-input v-model.trim="routeForm.endAddress" :disabled="dialogStatus=='detail'" :placeholder="dialogStatus=='detail'?'':'终点地址'" type="text"/> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="主要途径道路"> <el-input v-model.trim="routeForm.mainRoad" :disabled="dialogStatus=='detail'" :placeholder="dialogStatus=='detail'?'':'主要途径道路'" type="text"/> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="开始日期"> <el-date-picker v-model="routeForm.startDate" :disabled="dialogStatus=='detail'" :placeholder="dialogStatus=='detail'?'':'开始日期'" style="width: 100%" type="date" value-format="yyyy-MM-dd"/> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="结束日期"> <el-date-picker v-model="routeForm.endDate" :disabled="dialogStatus=='detail'" :placeholder="dialogStatus=='detail'?'':'结束日期'" style="width: 100%" type="date" value-format="yyyy-MM-dd"/> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="24"> <el-form-item label="准行时间段"> <el-checkbox-group v-model="accessTime"> <el-checkbox v-for="time in times" :label="time" :key="time" :disabled="dialogStatus=='detail'" style="width: 90px;line-height: 10px">{{ time }}:00</el-checkbox> </el-checkbox-group> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="24"> <el-form-item label="备注"> <el-input v-model.trim="routeForm.remarks" :disabled="dialogStatus=='detail'" :placeholder="dialogStatus=='detail'?'':'备注'" type="textarea" /> </el-form-item> </el-col> </el-row> </el-form> </el-collapse-item> <el-collapse-item title="(二)关联车辆" name="2"> <div class="infinite-list-wrapper" style="overflow:auto;height: 100px;padding-left: 40px;padding-top: 20px"> <el-checkbox-group v-model="removelist" class="checkbox" disabled> <el-checkbox v-for="item in carlist" :label="item.id" :key="item.id" style="width: 150px">{{ item.description }}</el-checkbox> </el-checkbox-group> </div> </el-collapse-item> <el-collapse-item title="(三)地图展示" name="3"> <div id="map"/> </el-collapse-item> </el-collapse> </app-container> </template> <script> import { getDictCode } from '@/api/dict' import { getRouteInfo } from '@/api/routeInfo' import DeptSelect from '@/components/DeptSelect' import L from 'leaflet' import 'leaflet/dist/leaflet.css' export default { components: { DeptSelect }, data() { return { dialogStatus: 'detail', // 对话框类型:create,update activeNames: ['1', '2', '3'], deptShow: true, routeId: '', map: null, list: [], alarmlist: [], cartypelist: [], accessTime: [], carlist: [], removelist: [], pathlist: [], baselayer: [], markerlayer: null, routeForm: { id: '', routeName: '', alarmType: '', alarmDistance: '', startAddress: '', endAddress: '', mainRoad: '', startDate: '', endDate: '', accessTime: '', remarks: '' }, // 表单 times: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], options: [{ value: '0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23', label: '全天(0-23)' }, { value: '8,9,10,11,12,13,14,15,16,17,18', label: '工作时间段(8-18)' }, { value: '8,9,10,11,12', label: '上午工作时间段(8-12)' }, { value: '14,15,16,17,18', label: '下午工作时间段(14-18)' }, { value: '-1', label: '自定义时间段' }], rules: { routeName: [{ required: true, message: '路线描述不能为空', trigger: ['blur', 'change'] }], alarmType: [{ required: true, message: '报警类型必选', trigger: ['blur', 'change'] }], alarmDistance: [{ required: true, message: '偏离报警距离不能为空', trigger: ['blur', 'change'] }] } } }, created() { this.initdata() }, mounted() { getDictCode('routeAlarmType').then(response => { this.alarmlist = response.data }) getDictCode('carType').then(response => { this.cartypelist = response.data }) this.initMap() this.initdata() }, methods: { initdata() { if (this.$route.query) { this.routeId = this.$route.query.id this.routeForm = { id: this.$route.query.id, routeName: this.$route.query.routeName, alarmType: this.$route.query.alarmType, alarmDistance: this.$route.query.alarmDistance, startAddress: this.$route.query.startAddress, endAddress: this.$route.query.endAddress, mainRoad: this.$route.query.mainRoad, startDate: this.$route.query.startDate, endDate: this.$route.query.endDate, accessTime: this.$route.query.accessTime, remarks: this.$route.query.remarks } if (this.routeForm.accessTime.length !== 0) { var accesslist = this.routeForm.accessTime.split(',') this.accessTime = [] for (var i = 0; i < accesslist.length; i++) { this.accessTime.push(Number(accesslist[i])) } } } getRouteInfo(this.routeId).then(response => { this.carlist = response.data.carList this.removelist = [] for (var i = 0; i < this.carlist.length; i++) { this.removelist.push(this.carlist[i].id) } this.pathlist = [] for (i = 0; i < response.data.pathList.length; i++) { var item = [Number(response.data.pathList[i].startLat), Number(response.data.pathList[i].startLng)] this.pathlist.push(item) if (i === response.data.pathList.length - 1) { item = [Number(response.data.pathList[i].endLat), Number(response.data.pathList[i].endLng)] this.pathlist.push(item) } } if (this.pathlist.length !== 0) { this.drawmap() } }) }, initMap() { const map = L.map('map', { minZoom: 3, maxZoom: 18, center: [27.75962, 116.06021], zoom: 12, zoomControl: false, attributionControl: false, crs: L.CRS.EPSG3857 }) 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)) }, 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。 } } }, setCenter(points) { // 获取折线中心点坐标 if (points.length > 0) { let maxLng = points[0][1] let minLng = points[0][1] let maxLat = points[0][0] let minLat = points[0][0] let res for (let 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] } const cenLng = (parseFloat(maxLng) + parseFloat(minLng)) / 2 const cenLat = (parseFloat(maxLat) + parseFloat(minLat)) / 2 this.map.setView({ lat: cenLat, lng: cenLng }) } }, drawmap() { var myStyle = { 'color': '#409eff', 'weight': 4.5, 'opacity': 0.7 } L.polyline(this.pathlist, myStyle).addTo(this.map) var Icon for (var i = 0; i < this.pathlist.length; i++) { if (i === 0) { Icon = L.icon({ iconUrl: require('../../assets/global_images/start.png'), iconSize: [45, 45] }) } else if (i === this.pathlist.length - 1) { Icon = L.icon({ iconUrl: require('../../assets/global_images/end.png'), iconSize: [45, 45] }) } else { Icon = L.divIcon({ className: 'my-div-icon', // 自定义icon css样式 iconSize: [15, 15]// 点大小 }) } L.marker([this.pathlist[i][0], this.pathlist[i][1]], { icon: Icon }).addTo(this.map) } this.setZoom(this.pathlist) } } } </script> <style rel="stylesheet/scss" lang="scss"> /*#detailroute . {*/ /*font-size: 15px ;*/ /*font-weight: bold;*/ /*}*/ #detailroute .el-checkbox__label { font-size: 15px ; font-weight: bold; } #detailroute .el-form-item { margin-bottom: 18px; } #detailroute .el-dialog__body { padding-top: 0px ; padding-left: 0px; padding-right: 0px; } #map { width:100%; height:50vh; } .my-div-icon { width: 10px; height: 10px; background-color: orange; border-radius: 50%; } #detailroute .el-form-item { margin-bottom: 10px; } .route-coll{ .el-collapse-item__header{ font-weight: bolder; margin-left: 10px; } } </style>