共计 6305 个字符,预计需要花费 16 分钟才能阅读完成。
需要 & 图例
题目性能分为 2 局部的需要:
- 【原需要】填写地址:省市区(下拉)+ 详情(输出),
【新需要】原需要放弃不变,然而减少快捷方式抉择地址,a. 减少地图搜索选中后 回填地址 b. 罕用地址 / 历史地址 列表, 选中后 回填地址;
图示阐明:
所有图示案例均为代码性能展现用,不思考好看性。
图示 1:
图示 2:
- 天文编码:地址转为经纬度;逆天文编码:经纬度转为地址;
【需要】:地图关上中心点默认在 ip 所在的城市;依据历史 GPS 数据展现车辆的历史轨迹信息,点击轨迹点展现信息窗体,右侧展现中显示以后车辆的所在的经纬度对应的具体地址;
图示 3:(中心点默认在 ip 所在的城市)
图示 4:(依据 GPS 数据展现车辆历史轨迹,基于后端返回的数据展现)
图示 5:(前端模仿数据,展现轨迹,点击展现信息窗体,右侧展现逆天文编码信息)
图示 6:(依据地址信息转为经纬度,标记在地图上)
main.js
import VueAMap from 'vue-amap'; // 命名尽量与 AMap 做辨别
Vue.use(VueAMap);
VueAMap.initAMapApiLoader({
key: 'your key',
plugin: [
"AMap.Autocomplete",
"AMap.PlaceSearch",
"AMap.Scale",
"AMap.ToolBar",
"AMap.OverView",
'AMap.MapType',
'AMap.PolyEditor',
'AMap.CircleEditor',
"AMap.Geolocation",
"AMap.Geocoder",
"AMap.CitySearch",
],
v: '1.4.15',
uiVersion: "1.1"
});
window._AMapSecurityConfig = {securityJsCode: 'your security js code',}
构造以图例 1、2 为根底,其余的性能仅以逻辑为主,以阐明为准
所有款式代码均省略
省市区下拉是通过拜访后端接口,这里须要将地图选点中取得的省市区的名字传给后端,失去下拉须要的 codes
罕用 / 历史 选点列表是通过后端接口取得,接口逻辑略,只展现数据结构
map-dialog.vue
template
<!-- 弹窗相干代码略 -->
<div class="flex">
<!-- 右边 -->
<el-amap
vid="amapContainer"
:center="amap.center"
:plugin="amap.plugin"
:zoom="amap.zoom"
:zoomEnable="true"
class="amap"
>
<!-- 搜寻性能 -->
<el-amap-search-box
:search-option="searchOption"
:on-search-result="onSearchResult"
class="search-box"
v-if="params.show"
>
</el-amap-search-box>
<!-- 搜寻后失去的点,可拖拽从新选点,点击确认选点 -->
<el-amap-marker
:clickable="true"
:draggable="true"
:events="amap.events"
:position="amap.marker"
/>
</el-amap>
<!-- 左边 -->
<el-tabs v-model="activeName" type="border-card">
<el-tab-pane label="罕用" name="first">
</el-tab-pane>
<el-tab-pane label="历史" name="second">
</el-tab-pane>
<el-table :data="dataList" border height="100%">
<el-table-column label="省市区">
<template slot-scope="scope">
<span>{{scope.row.province+scope.row.city+scope.row.district}}</span><br>
</template>
</el-table-column>
<el-table-column label="具体地址" prop="address"></el-table-column>
<el-table-column label="操作" width="60">
<template slot-scope="scope">
<span class="blue" @click="selectData(scope.row)"> 抉择 </span>
</template>
</el-table-column>
</el-table>
</el-tabs>
</div>
script
import {GET_CITYS_CODES} from '@/api/xx/index.js'; // 用地图失去的省市区名称换省市区下拉 codes
export default {
props: {
params: {
type: Object,
default: {},},
},
data() {
let self = this;
return {
activeName: "first",
amap: {
zoom: 9,
center: [0, 0],
plugin:['ToolBar'],
marker: [0, 0],
events: {click(e) {self.markerClick(e) }, // 选点点击事件
dragend(e) {self.dragEnd(e) }, // 选点拖拽事件
}
},
searchOption: {
city: '',
citylimit: true
},
// dataList 原本是后端接口取得,这里不重要,只作数据结构展现
dataList: [{
province: "四川省",
city: "成都市",
district: "高新区",
address: "仁和街阿斯顿路 250 号",
codes: ['510000', '510100', '510107']
}],
obj: {},
addr: ""
}
},
methods: {
// 能够放在专门的 utils 文件中,这里为了不便展现,放在 methods 里
// 获取以后 ip 所在城市
getCurrentCity() {return new Promise((resolve, reject) => {
let city;
AMap.plugin('AMap.CitySearch',function(){city = new AMap.CitySearch()
})
city.getLocalCity(function (status, result) {if (status === 'complete' && result.info === 'OK') {resolve(result.bounds.oc)
} else {reject('未检测到该地址')
}
});
})
},
// 能够放在专门的 utils 文件中,这里为了不便展现,放在 methods 里
// 逆天文编码:经纬度转为地址;getPositionByLonLats(lnglat) {return new Promise((resolve, reject) => {
let geocoder;
AMap.plugin('AMap.Geocoder',function(){geocoder = new AMap.Geocoder()
})
geocoder.getAddress(lnglat, function (status, result) {if (status === 'complete' && result.info === 'OK') {resolve(result.regeocode)
} else {reject('未检测到该地址')
}
});
})
},
// 能够放在专门的 utils 文件中,这里为了不便展现,放在 methods 里
// 天文编码:地址转为经纬度(与逆天文编码相似,这里不在演示调用)getPositionByAddr(addr) {return new Promise((resolve, reject) => {
let geocoder;
AMap.plugin('AMap.Geocoder',function(){geocoder = new AMap.Geocoder()
})
geocoder.getLocation(addr, function (status, result) {if (status === 'complete' && result.geocodes.length) {resolve(result.geocodes[0].location)
} else {reject('未检测到该地址')
}
});
})
},
// 弹窗 open 事件:中心点默认在设在 ip 所在地址
setData() {this.getCurrentCity().then((res) => {this.amap.center = [];
this.amap.center.push(res.lng, res.lat);
})
},
// 点击搜寻列表后果
// 留神:返回的后果是数组,默认选中第一个,作为点坐标
async onSearchResult(pois) {
let self = this;
await this.getPositionByLonLats([pois[0].lng, pois[0].lat]).then((res) => {self.obj = { ...res.addressComponent};
self.addr = res.formattedAddress;
}).catch((err) => {errorMsg(err);
return
})
self.amap.center = [];
self.amap.center.push(pois[0].lng, pois[0].lat);
self.amap.marker = [];
self.amap.marker.push(pois[0].lng, pois[0].lat);
self.amap.zoom = 18;
},
// 点坐标拖拽完结
dragEnd(e) {
let self = this;
//
self.getPositionByLonLats([e.lnglat.lng, e.lnglat.lat]).then((res) => {self.obj = { ...res.addressComponent};
self.addr = res.formattedAddress;
}).catch((err) => {errorMsg(err);
return
})
},
// 点击点坐标,是否确认抉择
markerClick() {
let self = this;
self.$confirm(` 是否确认抉择【${this.addr}】?`, "确认抉择", {
closeOnClickModal: false,
cancelButtonClass: "cancel-btn",
confirmButtonClass: "delete-btn",
}).then(() => {
let a = self.obj.province;
let b = self.obj.city;
let c = self.obj.district;
// 将点坐标省市区名称传给后端,获取省市区下拉 codes
// 留神:直辖市,高德不会返回市名称,后端要求,直辖市 省市同名
GET_CITYS_CODES([a, b?b:a, c]).then((res) => {if (res.code === 10000) {
let info = {
address: self.obj.township+self.obj.street+self.obj.streetNumber,
codes: res.result
}
// 将确认信息传给父组件
self.cancel(info);
}
});
})
.catch(() => {});
},
// 罕用 / 历史列表 抉择按钮
selectData(data) {
let info = {
address: data.address,
codes: data.codes
}
// 将抉择信息传给父组件
this.cancel(info);
},
其余性能的
template
// 构造与后面的 template 相似,这里只保留 el-amap
<el-amap
vid="amapContainer2"
:center="amap.center"
:plugin="amap.plugin"
:zoom="amap.zoom"
:zoomEnable="true"
class="amap"
>
<!-- 轨迹 -->
<el-amap-polyline
:stroke-weight="6"
:path="amap.path"
line-join="round"
stroke-color="#00BD00"
/>
<!-- 点 -->
<el-amap-marker
v-for="(item, i) in pathData"
:key="i+Math.random()"
:clickable="true"
:position="item.marker"
:events="{click(e){markerClick(e)} }"
/>
<!-- 信息窗体 -->
<el-amap-info-window
:auto-move="true"
:close-when-click-map="true"
:is-custom="true"
:offset="[-20, -30]"
:position="info.marker"
:visible="info.visible"
v-if="info.visible"
>
<div id="info-window">
<p>{{info.waybillNo}}</p>
<p>{{info.plate}}</p>
<p>{{info.phone}}</p>
<p>{{info.address}}</p>
</div>
</el-amap-info-window>
</el-amap>
script
data() {
return {
// 其余相似的略
info: {}, // 信息窗体
infoList: [] // 信息窗体汇合}
},
methods: {
// 点击坐标点弹出 信息窗体
markerClick(e) {
let self = this;
// 第一次点击 才给所有的信息窗体赋值(为了演示不便放在这里,赋值操作依据理论需要失常操作)if (self.infoList.length !== self.pathData.length) {for (let i = 0; i < self.pathData.length; i++) {let obj = {...self.pathData[i]};
obj.visible = false
self.infoList.push(obj);
}
// 切换信息窗体手动敞开所有窗体的 visible
} else {for (let i = 0; i < self.infoList.length; i++) {self.infoList[i].visible = false
}
}
// 清空上一个信息窗体的信息
self.info = {};
let arr = [e.target.w.position.lng, e.target.w.position.lat];
let index = self.pathData.findIndex(i => i.marker.toString() === arr.toString());
this.$nextTick(() => {self.info = self.infoList[index];
self.$set(self.info, 'visible', true);
})
},
}
正文完