vue3移动端腾讯地图坐标拾取,获取当前定位(腾讯、高德、百度、天地图),火星坐标GCJ-02–>百度坐标BD-09,根据坐标经纬度计算两点距离的方法,点击链接打开地图导航的方法

vue3移动端腾讯地图坐标拾取,获取当前定位(腾讯、高德、百度、天地图),火星坐标GCJ-02–>百度坐标BD-09,根据坐标经纬度计算两点距离的方法,点击链接打开地图导航的方法,第1张

文章目录 前言地图选点(坐标拾取 移动端)一、调用示例二、调用方法 地图选点(坐标拾取 pc端)获取当前定位一、调用示例二、调用方法 other:高德地图、百度地图、天地图获取当前定位的方法一、高德地图二、百度地图(支持异步加载)三、天地图 腾讯、高德、百度地图坐标系相互转换的方法(火星坐标GCJ-02–>百度坐标BD-09)根据坐标经纬度计算两点距离的方法点击链接打开地图导航的方法总结


前言

具体请参考腾讯地图开发者平台 https://lbs.qq.com/webApi

tips:
1、无论是腾讯地图还是高德、百度、天地图,都建议使用https协议访问,否则会定位异常或不精确。
2、申请地图key的步骤已省略。


地图选点(坐标拾取 移动端)

地图选点组件,类似微信中的“发送位置”功能,该组件可以让用户快速、准确地选择并确认自己的当前位置,并将相关位置信息回传给开发者。


一、调用示例

二、调用方法

参考 地图选点组件

tips: 在微信开发者工具中自动d框显示地图信息是正常现象


地图选点(坐标拾取 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: 在微信开发者工具中自动d框显示地图信息是正常现象


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左右一年。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/941609.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-17
下一篇 2022-05-17

发表评论

登录后才能评论

评论列表(0条)

保存