1. 概述
项目开发中需要增加客户从地图中选择位置,省去输入框的步骤,并且还可以精确到经度纬度,便于后续的查询距离等操作
百度了一番,发现腾讯地图中有个这组件,官方概述如下:
地图选点组件,类似微信中的“发送位置”功能,该组件可以让用户快速、准确地选择并确认自己的当前位置,并将相关位置信息回传给开发者。
2. 注册登录腾讯地图官网创建应用
应用管理—我的应用—创建应用
这一步直接选择Webservice服务即可,当然也可以在服务中设置域名(仅白名单中的域名才可使用此key调用WebService服务,留空则不限制)
添加后就会获取到当前应用的LEY, 这个非常重要,后续在调用地图组件时会用到
3. 使用地图选点组件
开发文档—地图组件—地图选点组件
我们可以看到有两种调用方式
-
通过iframe内嵌调用,地图选点组件的页面会根据开发者设置的iframe宽高自适应。
-
通过页面跳转的方式调用该组件的时候,开发者需要设置backurl参数,用户点击选中的位置点后,页面跳转至开发者指定的返回地址(backurl),并将位置信息添加到回跳地址(backurl)上。
在这里我们具体项目具体实现,我们先采用第一种方式开发
4. 主要代码如下
<el-button type="success" size="small" @click="dialogVisible = true">地图选点</el-button>
<el-dialog
title="提示"
size="small"
:close-on-click-modal="false"
:visible.sync="dialogVisible"
width="60%">
<div>
<iframe id="mapPage" src="https://apis.map.qq.com/tools/locpicker?search=1&type=1&key='上面创建的 KEY'&referer=myapp&total=10" frameborder="0" width="100%" height="100%"></iframe>
</div>
<span class="dialog-footer">
<el-button type="primary" @click="xuandian()">确 定</el-button>
</span>
</el-dialog>
<script>
window.addEventListener('message', function (event) {
// 接收位置信息,用户选择确认位置点后选点组件会触发该事件,回传用户的位置信息
var loc = event.data
if (loc && loc.module == 'locationPicker') { // 防止其他应用也会向该页面post信息,需判断module是否为'locationPicker'
localStorage.setItem('poiaddress', loc.poiaddress)
localStorage.setItem('lat', loc.latlng.lat)
localStorage.setItem('lng', loc.latlng.lng)
}
}, false)
</script>
5. 返回的位置信息格式
{
module:'locationPicker',
latlng: {
lat: 22.233878,
lng: 114.201344
},
poiaddress: "香港特别行政区南区南区区南区泳滩道",
poiname: "浅水湾海滩",
cityname: "香港特别行政区
}
这样我们就选点成功,直接将数据回传接口进行处理即可
6. 附带根据经纬度计算两个坐标之间的距离的工具方法
/*
计算两个经纬度之间的距离 结果单位:千米
*/
public static double getDistance(double lat1Str, double lng1Str, double lat1Str1, double lng1Str1) {
Double lat1 = Math.toRadians(lat1Str);
Double lng1 = Math.toRadians(lng1Str);
Double lat2 = Math.toRadians(lat1Str1);
Double lng2 = Math.toRadians(lng1Str1);
// 纬度之差
double a = lat1 - lat2;
// 经度之差
double b = lng1 - lng2;
// 计算两点距离的公式
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * SysDefaultID.EARTH_RADIUS;
BigDecimal bg = new BigDecimal( s / 1000.00);
return bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
}