700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 省-市-区三级联动选择地址 + 地图定位(高德api定位获取位置信息) 互相联动显示

省-市-区三级联动选择地址 + 地图定位(高德api定位获取位置信息) 互相联动显示

时间:2022-08-22 18:54:33

相关推荐

省-市-区三级联动选择地址 + 地图定位(高德api定位获取位置信息) 互相联动显示

一,前言

需求:省市区三级联动下拉选择出数据并地图显示位置,地图上选择定位位置三级联动反显出省市区;

准备:

1.需要全国地址完整(省市区-地区code)的area.json,

百度云盘下载地址 提取码:ufyz (另本已上传csdn资源,设置了几次0c币,但是系统一直自动给改要4-8C币,已弃)

2.地址定位这里用的是高德api故需要申请高德web开发相关申请配置 见这篇。

二,实现

1.utils.js自用工具类

@utils/area/index是标题一 内放置的 area-index.js 资源,自己项目使用自己的资源路径

/*** @param arr 城市地址三级联动选择器,选择出的code 数组* @return 返回解析出 省-市-区/县 的名字 addObj对象*/import AreaData from '@/utils/area/index'export function areaCode2AreaName(arr) {// console.log('areaCode2AreaName()-code名转地址', arr)const [provinceCode, cityCode, countyCode] = arrlet _province, _city, _countyconst _areaData = AreaDatalet addObj = {}if (_areaData.length > 0) {for (const k in _areaData) {if (_areaData[k].value === provinceCode) {_province = _areaData[k].labelconst _areaData2 = _areaData[k].childrenfor (const k2 in _areaData2) {if (_areaData2[k2].value === cityCode) {_city = _areaData2[k2].labelconst _areaData3 = _areaData2[k2].childrenfor (const k3 in _areaData3) {if (_areaData3[k3].value === countyCode) {_county = _areaData3[k3].labelbreak}}}}}}}addObj = {province: _province,city: _city,county: _county}return addObj}/*** @param arr 城市地址三级联动选择器,选择出的code 数组* @return 返回解析出 省-市-区/县 的code编码 addObj对象*/export function areaName2AreaCode(arr) {// console.log('areaName2AreaCode()-地址名转code', arr)const [provinceName, cityName, countyName] = arrlet _province, _city, _countyconst _areaData = AreaDatalet addObj = {}if (_areaData.length > 0) {for (const k in _areaData) {if (_areaData[k].label === provinceName) {_province = _areaData[k].value// console.log('areaName2AreaCode()-地址名转code-_province', _province)// 重庆市 500000 ,北京市 110000 , 上海市 310000, 天津市 120000, 香港特别行政区 810000, 澳门特别行政区 820000if (_province === '500000' || _province === '110000' || _province === '310000' || _province === '120000'|| _province === '810000' || _province === '820000') {const _areaData2 = _areaData[k].childrenlet now_cityName = provinceNameif (provinceName === '香港特别行政区' || provinceName === '澳门特别行政区') {now_cityName = provinceName.replace('特别行政区', '')}for (const k2 in _areaData2) {if (_areaData2[k2].label === now_cityName) {_city = _areaData2[k2].valueconst _areaData3 = _areaData2[k2].childrenfor (const k3 in _areaData3) {// 兼容处理 countyName输入的值中有 XX新区 及 XX区 这种值不确定 不匹配问题let countCountyName = ''if (countyName.indexOf('新区') !== -1) {countCountyName = countyName.substring(0, countyName.indexOf('新区'))} else {countCountyName = countyName}if (_areaData3[k3].label.indexOf(countCountyName) !== -1) {_county = _areaData3[k3].valuebreak}}}}} else {const _areaData2 = _areaData[k].childrenfor (const k2 in _areaData2) {if (_areaData2[k2].label === cityName) {_city = _areaData2[k2].valueconst _areaData3 = _areaData2[k2].childrenfor (const k3 in _areaData3) {// 兼容处理 countyName输入的值中有 XX新区 及 XX区 这种值不确定 不匹配问题let countCountyName = ''if (countyName.indexOf('新区') !== -1) {countCountyName = countyName.substring(0, countyName.indexOf('新区'))} else {countCountyName = countyName}if (_areaData3[k3].label.indexOf(countCountyName) !== -1) {_county = _areaData3[k3].valuebreak}}}}}}}}addObj = {provinceCode: _province,cityCode: _city,countyCode: _county}return addObj}// String: null => ''export function stringNullToValue(string) {let nowStr = ''if (string) {nowStr = string}return nowStr}

2.positionLocation.js 高德地图定位经纬度转地址

/*** CopyRight zh* /03/31* positionLocation.js* version : 1.0.0*/'use strict'// import Vue from 'vue'// import AMap from 'AMap'// Vue.use(AMap)import Axios from 'axios'/*** @param address 详细地址 省-市-区* @param callback 回调函数 返回resData* @return resData: {* status: true, // 是否成功data: null, // 返回数据message: null, // 返回提示信息* }* */export function getLngLat(address, callback) {console.log('getLngLat()-',address)const resData = {status: true,data: null,message: null,}// 根据地址获取经纬度Axios.get('/v3/geocode/geo?key=这里放自己的高德密钥&&address='+address).then(res=>{if(res.status ===200 && res.data.info==='OK'){let resp = res.data.geocodes[0]// console.error("getLngLat()-resp", resp)if(resp){resData.data = resp.location.split(',')resData.message = '获取经纬度成功'callback(resData)}else {console.error("不存在该位置信息")resData.status = falseresData.message = '不存在该位置信息'callback(resData)}}else {console.error("获取经纬度信息失败")resData.status = falseresData.message = '获取经纬度信息失败'callback(resData)}})}/*** @param longitude 经度 英文:longitude 114.044815* @param latitude 纬度 英文:latitude 22.687373* @param callback 回调函数 返回resData* @return resData: {* status: true, // 是否成功data: null, // 返回数据message: null, // 返回提示信息* }* */export function getLocation(longitude, latitude, callback){// const that = thisconst location = longitude + ',' + latitudeconsole.log('getLocation()-location',location)const resData = {status: true,data: null,message: null,}const nowLocation = {lat: '', // 纬度lon: '', // 经度province: '', // 省city: '', // 市district: '', // 区 县street: '', // 街道、乡镇nowPlace: '', // 省-市-区addressDetail: '' // 详细地址}// 根据经纬度获取地址Axios.get('/v3/geocode/regeo?key=这里放自己的高德密钥&location='+location).then(res=>{if(res.status === 200 && res.data.info==='OK'){let resp= res.data.regeocode.addressComponentconst addressDetails = res.data.regeocode.formatted_address// console.log('getLocation()-resp',resp)if(resp){nowLocation.province = resp.provinceif(resp.province ==='上海市'||resp.province ==='重庆市'||resp.province ==='天津市'||resp.province ==='北京市'||resp.province ==='香港特别行政区'||resp.province ==='澳门特别行政区'){if (resp.province === '香港特别行政区' || resp.province === '澳门特别行政区') {nowLocation.city = resp.province.replace('特别行政区', '')} else {nowLocation.city = resp.province}} else {nowLocation.city = resp.city}// 如果例如: 东莞市-虎门镇 返回信息 district 值为 [], 则 东莞市 区级值 用 township街道值 进行回填// console.log('resp.district instanceof Array', resp.district instanceof Array)if (resp.district instanceof Array && resp.district.length === 0) {nowLocation.district = resp.township} else {nowLocation.district = resp.district}nowLocation.street = resp.townshipnowLocation.nowPlace = nowLocation.province + nowLocation.city + nowLocation.districtnowLocation.lon = longitudenowLocation.lat = latitudenowLocation.addressDetail = resp.neighborhood.nameif (resp.district !== false){nowLocation.addressDetail = addressDetails.split(resp.district)[1]}else if(resp.city !== false){nowLocation.addressDetail = addressDetails.split(resp.city)[1]}resData.data = nowLocationresData.message = '获取位置信息成功'callback(resData)} else {console.error("不存在该位置信息")resData.status = falseresData.message = '不存在该位置信息'callback(resData)}}else {console.error("获取地址信息失败")resData.status = falseresData.message = '获取地址信息失败'callback(resData)}})}

3.这里是页面vue

<template><!-- 省市区三级联动 --><el-form label-width="110px" ref="objEditFrom" :model="objEditData"><el-form-item label="发生地点" prop="selectedOptionsStart"><el-cascaderclass="w184"placeholder="任意搜索地区":options="areaData"filterablechange-on-select@change="startAddressChange"v-model="objEditData.selectedOptionsStart"></el-cascader></el-form-item><el-form-item label="街道/乡镇" prop="street"><el-input type="text" clearable v-model="objEditData.street" class="w184" @change="detailChange"></el-input></el-form-item><el-form-item label="详细地址" prop="addressDetails"><el-input type="text" clearable v-model="objEditData.addressDetails" class="w184" @change="detailChange"></el-input></el-form-item></el-from><!-- 地图 --><div><!-- 地图容器 --><div id="amap-container" style="width:400px;height: 300px;"></div></div></template><style>.w184{width: 184px!important;}</style><script>import Area from "@/utils/area/index";import * as Utils from "@/utils/index";import * as LocationAMap from "@/utils/positionLocation/positionLocation";export default {data() {return {objEditData: {selectedOptionsStart: ["", "", ""], // 省市区 编码addressDetails: null, // 出险地点 详细地址longitude: null,latitude: null},areaData: Area, // 省-市-区三级联动选择selectArea: {province: '',city: '',county: '',street: '',addressDetails: ''},}},mounted() {// this.initFunc();},methods: {initFunc() {const that = this;const province = '广东省'const city = '深圳市'const county = '南山区'const street= '西乡街道'const addressDetails = '详细地址'// 解析 省市区 编码const { provinceCode, cityCode, countyCode } = Utils.areaName2AreaCode([province, city, county]);// 如果是编辑 已有 省 市 区 数据进行设置 三级联动显示对应 省市区that.objEditData = {selectedOptionsStart: [provinceCode, cityCode, countyCode],addressDetails}that.selectArea = {province, city, county, street, addressDetails}that.getLngLatFunc(); // 地址转经纬度},initMap(longitude, latitude,zoom) {console.log("initMap()初始化");const that = this;// const newV = [116.397559, 39.89621]// center: new AMap.LngLat(nowLog, nowLat),const nowLog = longitude || 116.397559;const nowLat = latitude || 39.89621;let zoomdata= zoom?zoom:11const mapObj = new AMap.Map("amap-container", {center: [nowLog, nowLat],zoom: zoomdata // 初始化地图时显示的地图放大等级});// console.log("initMap()初始化-nowLog", nowLog, nowLat);const markerNow = {name: "",lnglat: [nowLog, nowLat]};createMarkerFunc(markerNow);// 地图点击事件const showInfoClick = function(e) {console.log("showInfoClick()触发了地图click事件-e");// e.lnglat.getLng(),e.lnglat.getLat()const markerItem = {name: "",lnglat: [e.lnglat.getLng(), e.lnglat.getLat()]};createMarkerFunc(markerItem);setBoundsFunc(markerItem);that.getLocationFunc(e.lnglat.getLng(), e.lnglat.getLat());};// 监听 地图点击事件// if (!that.makeInputDisabled) {// mapObj.on("click", showInfoClick);// }mapObj.on("click", showInfoClick);// -------------自定义方法------------------// 指定当前地图显示范围,参数bounds为指定的范围function setBoundsFunc(markerItem) {console.log("setBoundsFunc()");const start = [Number(markerItem.lnglat[0]) - 0.01,Number(markerItem.lnglat[1]) - 0.01];const end = [Number(markerItem.lnglat[0]) + 0.01,Number(markerItem.lnglat[1]) + 0.01];const mybounds = new AMap.Bounds(start, end);mapObj.setBounds(mybounds);}// 创建Marker方法function createMarkerFunc(markerItem) {console.log("createMarker()");mapObj.clearMap(); // 清除地图覆盖物// 创建一个 Marker 实例:const marker = new AMap.Marker({map: mapObj,position: new AMap.LngLat(markerItem.lnglat[0], markerItem.lnglat[1])// 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]});// 将创建的点标记添加到已有的地图实例:mapObj.add(marker);}},// 街道/ 乡镇 、详细地址 修改时detailChange() {this.selectArea.street = this.objEditData.streetthis.selectArea.addressDetails = this.objEditData.addressDetailsthis.getLngLatFunc()},// 通过 地址 获取 经纬度getLngLatFunc() {const that = this;const { province, city, county, street, addressDetails } = that.selectArea;const address = Utils.stringNullToValue(province) + Utils.stringNullToValue(city) + Utils.stringNullToValue(county) + Utils.stringNullToValue(street) + Utils.stringNullToValue(addressDetails);LocationAMap.getLngLat(address, function(resData) {if (resData.status) {console.log("getLngLatFunc()-", resData.data);that.LngLat = resData.data;that.objEditData.longitude = that.LngLat[0];that.objEditData.latitude = that.LngLat[1];// 解决 地图 异步渲染问题that.$nextTick(() => {that.initMap(that.objEditData.longitude, that.objEditData.latitude);});} else {that.$message({message: resData.message,type: "warning",duration: 2000});}});},// 通过经纬度获取 地址getLocationFunc(longitude, latitude) {const that = this;// const location = longitude + ',' + latitude// console.log('getLocationFunc()-location',location)LocationAMap.getLocation(longitude, latitude, function(resData) {if (resData.status) {const { province, city, district, addressDetail, street } = resData.data;that.selectArea = {province: province,city: city,county: district,street: street,addressDetails: addressDetail};// 解析 省市区 编码const {provinceCode,cityCode,countyCode} = Utils.areaName2AreaCode([province, city, district]);that.objEditData.selectedOptionsStart = [provinceCode,cityCode,countyCode];that.objEditData.addressDetails = addressDetail;that.objEditData.longitude = longitude;that.objEditData.latitude = latitude;} else {this.$message({message: resData.message,type: "warning",duration: 2000});}});},// 三级连选 起运地地址startAddressChange(val) {const selectArr = val;console.log("startAddressChange()-val", val);this.selectArea = Utils.areaCode2AreaName(selectArr);this.getLngLatFunc();}}}</script>

4.实现效果截图

选择省市区或详细地址-地图显示标记位置

地图选择定位-反显省市区三级联动+详细地址

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。