文章目录
前言
具体请参考腾讯地图开发者平台
https://lbs.qq.com/webApi
tips:
1、无论是腾讯地图还是高德、百度、天地图,都建议使用https协议访问,否则会定位异常或不精确。
2、申请地图key的步骤已省略。
地图选点(坐标拾取 移动端)
地图选点组件,类似微信中的“发送位置”功能,该组件可以让用户快速、准确地选择并确认自己的当前位置,并将相关位置信息回传给开发者。
一、调用示例
二、调用方法
参考 地图选点组件
tips: 在微信开发者工具中自动弹框显示地图信息是正常现象
地图选点(坐标拾取 pc端)
参考这个大佬的方法
https://blog.csdn.net/nightstar84/article/details/123770337
获取当前定位
引入封装好的JS模块,调起前端定位组件,通过封装好的接口获取位置信息
参考 地图定位组件
一、调用示例
1、在index.html中引入 js文件
https://mapapi.qq.com/web/mapComponents/geoLocation/v/geolocation.min.js
2、代码示例
1、调用 initMap 方法时 使用了一个定时器延后加载方法。
2、initMap 方法要在 onMounted nextTick 之后使用
// 渲染完毕后调用
onMounted(() => {
nextTick(() => {
initMap()
})
})
let initMapIdx = 0;
const initMap = () => {
if (!window.qq.maps && initMapIdx < 10) {
setTimeout(() => {
initMapIdx += 1;
initMap()
}, 500)
return false
}
const geolocation = new window.qq.maps.Geolocation(
'你申请的地图key', // 申请的腾讯地图key(必填)
"myapp" // 申请的腾讯地图key名称(非必填,最好填一下)
);
// 回调的第一次参数为成功后具体的位置信息
geolocation.getLocation(
postion => {
// console.log("成功", postion);
// alert(JSON.stringify(postion))
onComplete(postion)
},
err => {
console.log("定位失败", err);
}
);
}
二、调用方法
参考 地图定位组件
tips: 在微信开发者工具中自动弹框显示地图信息是正常现象
other:高德地图、百度地图、天地图获取当前定位的方法
申请地图key的步骤省略
自己去对应的官网申请
一、高德地图
1、在index.html中引入 js文件
https://webapi.amap.com/maps?v=1.4.15&key=你申请的key
2、代码示例:
AMap.plugin(['AMap.Geolocation', 'AMap.ToolBar'], function () {
// console.log(333)
let geolocation = new AMap.Geolocation({
enableHighAccuracy: true, //是否使用高精度定位,默认:true
timeout: 10000, //超过10秒后停止定位,默认:5s
buttonPosition: 'LB', //定位按钮的停靠位置
buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
zoomToAccuracy: true, //定位成功后是否自动调整地图视野到定位点
})
map.addControl(geolocation)
geolocation.getCurrentPosition(function (status, result) {
if (status == 'complete') {
// console.log(444, result)
// alert(JSON.stringify(result))
// onComplete(result.position) // 成功的处理方法
} else {
// console.log(555, result)
// alert(JSON.stringify(result))
console.log('失败原因排查信息:', result.message)
}
})
二、百度地图(支持异步加载)
这里通过异步加载注入的方式,你也可以像上面那样在 index.html 中直接引入 js
1、创建公共文件 bdBmay.js
2、代码:
function initMap() {
const AK = ""; //你的AK
const BMap_URL =
"https://api.map.baidu.com/api?v=2.0&ak=" +
AK +
"&s=1&callback=onBMapCallback";
return new Promise((resolve) => {
// 如果已加载直接返回
if (typeof BMap !== "undefined") {
resolve(BMap);
return true;
}
// 百度地图异步加载回调处理
window.onBMapCallback = function () {
resolve(BMap);
};
// let getCurrentCityName = function () {
// return new Promise(function (resolve, reject) {
// let myCity = new BMap.LocalCity()
// myCity.get(function (result) {
// resolve(result.name)
// })
// })
// }
// 插入script脚本
let scriptNode = document.createElement("script");
scriptNode.setAttribute("type", "text/javascript");
scriptNode.setAttribute("src", BMap_URL);
document.body.appendChild(scriptNode);
});
}
// 定位
function getCity() {
initMap().then((BMap) => {
const geolocation = new BMap.Geolocation();
geolocation.getCurrentPosition(
(position) => {
let city1 = position.address.city; //获取城市信息
//获取省份信息
// let province = position.address.province;
console.log(city1);
// console.log(province)
},
(e) => {
console.log(e);
console.log("定位失败");
},
{
provider: "baidu",
}
);
});
}
三、天地图
1、在index.html中引入 js文件
https://api.tianditu.gov.cn/api?v=4.0&tk=你申请的key
2、代码示例:
//创建定位对象lo
let lo = new T.Geolocation();
//开始定位
setTimeout(() => { // 加入定时器确保页面已渲染 js已加载
lo.getCurrentPosition(fn);
}, 100);
//定位回调函数
let fn = (e) => {
// alert(JSON.stringify(e))
// Toast(`${res.latitude},${res.longitude}`)
context.commit('setUserLoaction', {
lat: e.lnglat.lat,
lng: e.lnglat.lng
})
getDetailLocation(e.lnglat.lng, e.lnglat.lat);
}
// 逆地址解析
function getDetailLocation(lng, lat) {
return new Promise(resolve => {
fetch(`https://api.tianditu.gov.cn/geocoder?postStr={'lon':${lng},'lat':${lat},'ver':1}&type=geocode&tk=你申请的key`)
.then((data) => {
return data.json();
}).then((data) => {
if (data.status == '0') {
// console.log(data.result)
// alert(JSON.stringify(data.result))
if (data.result.addressComponent) {
alert(JSON.stringify(data.result.addressComponent))
}
}
return resolve(data)
})
})
}
腾讯、高德、百度地图坐标系相互转换的方法(火星坐标GCJ-02–>百度坐标BD-09)
/* 火星坐标GCJ-02–>百度坐标BD-09 */
//高德坐标转百度(传入经度、纬度)
export function bd_encrypt(gg_lng, gg_lat) {
let X_PI = Math.PI * 3000.0 / 180.0;
let x = gg_lng,
y = gg_lat;
let z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * X_PI);
let theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * X_PI);
let bd_lng = z * Math.cos(theta) + 0.0065;
let bd_lat = z * Math.sin(theta) + 0.006;
return {
lng: bd_lng,
lat: bd_lat
};
}
//百度坐标转高德(传入经度、纬度)
export function bd_decrypt(bd_lng, bd_lat) {
let X_PI = Math.PI * 3000.0 / 180.0;
let x = bd_lng - 0.0065;
let y = bd_lat - 0.006;
let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
let gg_lng = z * Math.cos(theta);
let gg_lat = z * Math.sin(theta);
return {
lng: gg_lng,
lat: gg_lat
}
}
根据坐标经纬度计算两点距离的方法
const EARTH_RADIUS = 6378137.0; // 单位 M
const PI = Math.PI;
function getRad(d) {
return d * PI / 180.0;
}
/* *
* caculate the great circle distance
* @param {number} lat1
* @param {number} lng1
* @param {number} lat2
* @param {number} lng2
*/
export function getGreatCircleDistance(lat1, lng1, lat2, lng2) {
let radLat1 = getRad(lat1);
let radLat2 = getRad(lat2);
let a = radLat1 - radLat2;
let b = getRad(lng1) - getRad(lng2);
let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * EARTH_RADIUS;
s = Math.round(s * 10000) / 10000.0;
return s;
}
// 当然,我们都知道,地球其实并不是一个真正的圆球体,而是椭球,所以有了下面的公式:
// 这个公式计算出的结果要比第一个好一些,当然,最后结果的经度实际上还取决于传入的坐标的精度。
/* *
* approx distance between two points on earth ellipsoid
* @param {number} lat1
* @param {number} lng1
* @param {number} lat2
* @param {number} lng2
*/
export function getFlatternDistance(lat1, lng1, lat2, lng2) {
let f = getRad((lat1 + lat2) / 2);
let g = getRad((lat1 - lat2) / 2);
let l = getRad((lng1 - lng2) / 2);
let sg = Math.sin(g);
let sl = Math.sin(l);
let sf = Math.sin(f);
let s, c, w, r, d, h1, h2;
let a = EARTH_RADIUS;
let fl = 1 / 298.257;
sg = sg * sg;
sl = sl * sl;
sf = sf * sf;
s = sg * (1 - sl) + (1 - sf) * sl;
c = (1 - sg) * (1 - sl) + sf * sl;
w = Math.atan(Math.sqrt(s / c));
r = Math.sqrt(s * c) / w;
d = 2 * w * a;
h1 = (3 * r - 1) / 2 / c;
h2 = (3 * r + 1) / 2 / s;
return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg));
}
点击链接打开地图导航的方法
/**
* @description 点击链接跳转打开地图
* @param {number} data.lng 经度
* @param {number} data.lat 纬度
* @param {number} bdData.lng 百度地图经度
* @param {number} bdData.lat 百度地图纬度
* @param {string} data.name 位置名称
* @param {string} data.desc 位置详细信息(描述)
* @param {string} dataInfo.addressKeyword 搜索的位置信息(模糊查询)
* @param {string} dataInfo.city 城市名
*/
// 腾讯地图
`https://apis.map.qq.com/uri/v1/search?keyword=${dataInfo.addressKeyword}®ion=${dataInfo.city}&referer=xingcunyi`;
`https://apis.map.qq.com/uri/v1/geocoder?coord=${data.lat},${data.lng}&name=${data.name}`
// 高德地图
`https://uri.amap.com/marker?position=${data.lng},${data.lat}&name=${data.name}&coordinate=gaode&callnative=1`
// 百度地图
`https://api.map.baidu.com/marker?location=${bdData.lat},${bdData.lng}&title=${data.name}&content=${data.desc}&output=html`
总结
腾讯地图比较适合微信h5。
高德地图在手机上表现会更好一点,提供了丰富的自定义地图。
百度地图有http的定位方法可用,会有一点误差,与其它地图使用时记得转换两种坐标系。
天地图目前是在测试阶段,功能没有以上三种齐全,定位精度偏低,存在一些坑,最大的优势是商用免费,另外3种商用都得5W左右一年。