index.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // 高德地图获取定位
  2. // #ifdef H5
  3. import keyConfig from './mapKeyConfig';
  4. import AMapLoader from '@amap/amap-jsapi-loader';
  5. // #endif
  6. /**
  7. * 传入经纬度返回地址
  8. * @param {Array} lnglat 经纬度
  9. * @param {Boolean} geocode 是否解析地址信息
  10. * @returns {Promise} 返回promise
  11. **/
  12. const getAddress = (lnglat, geocode) => {
  13. return new Promise((resolve, reject) => {
  14. if (!geocode) {
  15. resolve();
  16. return;
  17. }
  18. const geocoder = new AMap.Geocoder({
  19. city: '全国', //城市设为北京,默认:“全国”
  20. radius: 1000, //范围,默认:500
  21. });
  22. geocoder.getAddress(lnglat, (status, result) => {
  23. if (status === 'complete' && result.regeocode) {
  24. resolve(result.regeocode);
  25. return;
  26. }
  27. reject(result);
  28. console.error('根据经纬度查询地址失败');
  29. });
  30. });
  31. };
  32. /**
  33. * 获取定位信息
  34. * @param {Boolean} geocode 是否解析地址信息
  35. * @returns {Promise} 返回定位信息
  36. **/
  37. const Geolocation = (AMap, geocode, options) => {
  38. return new Promise((resolve, reject) => {
  39. AMap.plugin('AMap.Geolocation', () => {
  40. const geolocation = new AMap.Geolocation(options);
  41. //getCurrentPosition 调用此方法可实现打开页面自动定位
  42. geolocation.getCurrentPosition(async (status, res) => {
  43. if (status === 'complete') {
  44. // 定位成功
  45. const { position } = res;
  46. const arrPosition = Array.isArray(position)
  47. ? position
  48. : [position.lng, position.lat]; // todo pc和app打印结果不一致
  49. const address = await getAddress(arrPosition, geocode);
  50. resolve({ ...res, position: arrPosition, address });
  51. return;
  52. }
  53. // 定位失败
  54. uni.showToast({
  55. title: '定位失败,请开启定位后重试',
  56. icon: 'none',
  57. });
  58. reject(res);
  59. });
  60. });
  61. });
  62. };
  63. //geocode 是否解析地址
  64. const appGetLocation = (option) => {
  65. return new Promise((resolve, reject) => {
  66. uni.getLocation({
  67. ...option,
  68. success: async (res) => {
  69. resolve(res);
  70. },
  71. fail: (err) => {
  72. reject(err);
  73. uni.showToast({
  74. title: '定位失败,请开启定位后重试',
  75. icon: 'none',
  76. });
  77. },
  78. });
  79. });
  80. };
  81. const defaultOpt = {
  82. // 默认配置
  83. type: 'wgs84',
  84. isHighAccuracy: true, //开启高精度定位
  85. };
  86. async function getAppLocation(option) {
  87. // 当前运行在app
  88. const appRes = await appGetLocation(option);
  89. const newRes = { ...appRes };
  90. if (option.geocode) {
  91. // 默认false,是否解析地址信息
  92. const { province, city, district, street, streetNum } =
  93. appRes.address;
  94. newRes.formattedAddress = `${province}${city}${district}${street}${streetNum}`; // 自定义的参数,拼接地址
  95. }
  96. return newRes;
  97. }
  98. async function getWebLocation(option) {
  99. window._AMapSecurityConfig = {
  100. securityJsCode: keyConfig.securityJsCode,
  101. };
  102. const AMap = await AMapLoader.load({
  103. key: keyConfig.key, // 申请好的Web端开发者Key,首次调用 load 时必填(plc-key)
  104. version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
  105. plugins: [
  106. 'AMap.DistrictSearch',
  107. 'AMap.Geocoder',
  108. 'AMap.AutoComplete ', //2.0版本是AMap.AutoComplete, 2.0以下是AMap.Autocomplete
  109. // 输入提示插件
  110. 'AMap.PlaceSearch', // POI搜索插件
  111. 'AMap.Scale', // 右下角缩略图插件 比例尺
  112. 'AMap.OverView', // 地图鹰眼插件
  113. 'AMap.ToolBar', // 地图工具条
  114. 'AMap.MapType', // 类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制
  115. 'AMap.PolyEditor', // 编辑 折线多,边形
  116. 'AMap.CircleEditor', // 圆形编辑器插件
  117. 'AMap.Geolocation', // 定位控件,用来获取和展示用户主机所在的经纬度位置], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
  118. ],
  119. });
  120. const { geocode } = option || {};
  121. // map初始化完成
  122. const res = await Geolocation(AMap, geocode, {
  123. enableHighAccuracy: true, //是否使用高精度定位,默认:true
  124. timeout: 10000, //超过10秒后停止定位,默认:5s
  125. GeoLocationFirst: true, //默认为false,设置为true的时候可以调整PC端为优先使用浏览器定位,失败后使用IP定位
  126. });
  127. // 返回结果保持跟uni.getLocation 一致
  128. const [longitude, latitude] = res.position;
  129. const address = res.address || {};
  130. const { province, city, district, street, streetNumber, cityCode } =
  131. address.addressComponent;
  132. const newData = {
  133. longitude,
  134. latitude,
  135. address: {
  136. // 文档参数说明https://uniapp.dcloud.net.cn/api/location/location.html
  137. country: '',
  138. province,
  139. city,
  140. district,
  141. street,
  142. streetNum: streetNumber,
  143. poiName: '',
  144. postalCode: '',
  145. cityCode,
  146. },
  147. formattedAddress: address.formattedAddress,
  148. };
  149. return newData;
  150. }
  151. /**
  152. * 获取定位,并返回定位信息
  153. * @param {Object} options uni.getLocation的配置项, h5只支持 geocode 是否解析地址信息
  154. * @returns {Promise} 返回promise
  155. **/
  156. export const getLocation = async (option = defaultOpt) => {
  157. const uniPlatform = uni.$u.sys().uniPlatform;
  158. if (uniPlatform === 'app') {
  159. const res = await getAppLocation(option);
  160. return res;
  161. }
  162. const webRes = await getWebLocation(option);
  163. return webRes;
  164. };