开发uniapp h5时,涉及到获取经纬度需求,起初在浏览器调试,获取经纬度失败,但是可以正常在手机上获取,只获取经纬度就没必要去用第三方sdk

封装通用js          amap-locationCur-web.js

/**
 * 通用地理位置获取工具(支持 H5、小程序、App)
 * 返回:经纬度 + 地址信息(国家、省、市、区、街道)
 * 
 * 使用方式:
 * import Location from '@/utils/location.js';
 * const res = await Location.getLocation();
 */

export default {
    /**
     * 获取当前位置(主入口)
     * @returns {Promise<Object>} 包含经纬度和地址信息
     */
    getLocation() {
      return new Promise((resolve, reject) => {
        // 判断是否为 H5 平台
        if (process.env.UNI_PLATFORM === 'h5') {
          this._getH5Location().then(resolve).catch(reject);
        } else {
          this._getUniLocation().then(resolve).catch(reject);
        }
      });
    },
  
    /**
     * H5 端使用浏览器原生 Geolocation API
     */
    _getH5Location() {
      return new Promise((resolve, reject) => {
        if (!navigator.geolocation) {
          reject(new Error('您的浏览器不支持地理定位功能'));
          return;
        }
  
        const options = {
          enableHighAccuracy: true,  // 高精度
          timeout: 10000,            // 10秒超时
          maximumAge: 1000          // 缓存1分钟
        };
  
        navigator.geolocation.getCurrentPosition(
          async (position) => {
            const coords = position.coords;
            const lat = coords.latitude;
            const lng = coords.longitude;
            const accuracy = coords.accuracy;
            const altitude = coords.altitude;
  
            try {
              // 获取地址信息(逆地理编码)
              const address = await this._reverseGeocodeH5(lat, lng);
              resolve({
                lat: lat,
                lng: lng,
                accuracy: Math.round(accuracy),
                altitude: altitude ? Math.round(altitude) : null,
                ...address,
                success: true
              });
            } catch (err) {
              // 解析失败仍返回坐标
              resolve({
                lat: lat,
                lng: lng,
                accuracy: Math.round(accuracy),
                altitude: altitude ? Math.round(altitude) : null,
                country: '未知',
                province: '未知',
                city: '未知',
                district: '未知',
                street: '未知',
                warning: '地址解析失败: ' + (err.message || '网络错误')
              });
            }
          },
          (error) => {
            let msg;
            switch (error.code) {
              case error.PERMISSION_DENIED:
                msg = '用户拒绝了定位权限请求';
                break;
              case error.POSITION_UNAVAILABLE:
                msg = '无法获取当前位置信息';
                break;
              case error.TIMEOUT:
                msg = '定位请求超时,请重试';
                break;
              default:
                msg = '定位失败:未知错误';
            }
            reject(new Error(msg));
          },
          options
        );
      });
    },
  
    /**
     * 小程序 / App 端使用 uni.getLocation
     */
    _getUniLocation() {
      return new Promise((resolve, reject) => {
        uni.getLocation({
          type: 'gcj02', // 使用国测局坐标系(微信推荐)
          enableHighAccuracy: true,
          timeout: 10000,
          success: async (res) => {
            const lat = res.latitude;
            const lng = res.longitude;
            const accuracy = res.accuracy;
            const altitude = res.altitude;
  
            try {
              const address = await this._reverseGeocodeUni(lat, lng);
              resolve({
                latitude: lat,
                longitude: lng,
                accuracy: Math.round(accuracy),
                altitude: altitude ? Math.round(altitude) : null,
                ...address,
                success: true
              });
            } catch (err) {
              resolve({
                latitude: lat,
                longitude: lng,
                accuracy: Math.round(accuracy),
                altitude: altitude ? Math.round(altitude) : null,
                country: '未知',
                province: '未知',
                city: '未知',
                district: '未知',
                street: '未知',
                warning: '地址解析失败: ' + (err.message || '网络错误')
              });
            }
          },
          fail: (err) => {
            let msg = '定位失败';
            if (err.errMsg.includes('auth deny')) {
              msg = '未授权定位,请在设置中开启位置权限';
            } else if (err.errMsg.includes('timeout')) {
              msg = '定位超时';
            } else if (err.errMsg.includes('fail')) {
              msg = '设备不支持或未开启GPS';
            }
            reject(new Error(msg));
          }
        });
      });
    },
  
    /**
     * H5 逆地理编码(模拟实现)
     * ⚠️ 实际项目请替换为真实 API:高德、腾讯地图等
     */
    _reverseGeocodeH5(lat, lng) {
      return new Promise((resolve, reject) => {
        // 模拟不同区域返回不同地址(随机)
        const mockAddresses = [
          { country: "中国", province: "广东省", city: "深圳市", district: "南山区", street: "科技南一路" },
          { country: "中国", province: "北京市", city: "北京市", district: "海淀区", street: "中关村大街" },
          { country: "中国", province: "上海市", city: "上海市", district: "浦东新区", street: "张江路" },
          { country: "中国", province: "浙江省", city: "杭州市", district: "西湖区", street: "文三路" },
          { country: "中国", province: "江苏省", city: "南京市", district: "鼓楼区", street: "中山北路" }
        ];
  
        // 模拟网络延迟
        setTimeout(() => {
          const randomIndex = Math.floor(Math.random() * mockAddresses.length);
          resolve(mockAddresses[randomIndex]);
        }, 800);
      });
    },
  
    /**
     * 小程序/App 逆地理编码(模拟)
     * ⚠️ 建议接入真实服务:
     * 腾讯地图:https://apis.map.qq.com/ws/geocoder/v1/
     * 高德地图:https://restapi.amap.com/v3/geocode/regeo
     */
    _reverseGeocodeUni(lat, lng) {
      return new Promise((resolve, reject) => {
        const mockAddresses = [
          { country: "中国", province: "广东省", city: "广州市", district: "天河区", street: "科韵路" },
          { country: "中国", province: "四川省", city: "成都市", district: "武侯区", street: "天府大道" },
          { country: "中国", province: "湖北省", city: "武汉市", district: "洪山区", street: "光谷大道" }
        ];
  
        setTimeout(() => {
          const randomIndex = Math.floor(Math.random() * mockAddresses.length);
          resolve(mockAddresses[randomIndex]);
        }, 1000);
      });
    }
  };

/**
 * 通用地理位置获取工具(支持 H5、小程序、App)
 * 返回:经纬度 + 地址信息(国家、省、市、区、街道)
 * 
 * 使用方式:
 * import Location from '@/utils/location.js';
 * const res = await Location.getLocation();
 */

export default {
    /**
     * 获取当前位置(主入口)
     * @returns {Promise<Object>} 包含经纬度和地址信息
     */
    getLocation() {
      return new Promise((resolve, reject) => {
        // 判断是否为 H5 平台
        if (process.env.UNI_PLATFORM === 'h5') {
          this._getH5Location().then(resolve).catch(reject);
        } else {
          this._getUniLocation().then(resolve).catch(reject);
        }
      });
    },
  
    /**
     * H5 端使用浏览器原生 Geolocation API
     */
    _getH5Location() {
      return new Promise((resolve, reject) => {
        if (!navigator.geolocation) {
          reject(new Error('您的浏览器不支持地理定位功能'));
          return;
        }
  
        const options = {
          enableHighAccuracy: true,  // 高精度
          timeout: 10000,            // 10秒超时
          maximumAge: 1000          // 缓存1分钟
        };
  
        navigator.geolocation.getCurrentPosition(
          async (position) => {
            const coords = position.coords;
            const lat = coords.latitude;
            const lng = coords.longitude;
            const accuracy = coords.accuracy;
            const altitude = coords.altitude;
  
            try {
              // 获取地址信息(逆地理编码)
              const address = await this._reverseGeocodeH5(lat, lng);
              resolve({
                lat: lat,
                lng: lng,
                accuracy: Math.round(accuracy),
                altitude: altitude ? Math.round(altitude) : null,
                ...address,
                success: true
              });
            } catch (err) {
              // 解析失败仍返回坐标
              resolve({
                lat: lat,
                lng: lng,
                accuracy: Math.round(accuracy),
                altitude: altitude ? Math.round(altitude) : null,
                country: '未知',
                province: '未知',
                city: '未知',
                district: '未知',
                street: '未知',
                warning: '地址解析失败: ' + (err.message || '网络错误')
              });
            }
          },
          (error) => {
            let msg;
            switch (error.code) {
              case error.PERMISSION_DENIED:
                msg = '用户拒绝了定位权限请求';
                break;
              case error.POSITION_UNAVAILABLE:
                msg = '无法获取当前位置信息';
                break;
              case error.TIMEOUT:
                msg = '定位请求超时,请重试';
                break;
              default:
                msg = '定位失败:未知错误';
            }
            reject(new Error(msg));
          },
          options
        );
      });
    },
  
    /**
     * 小程序 / App 端使用 uni.getLocation
     */
    _getUniLocation() {
      return new Promise((resolve, reject) => {
        uni.getLocation({
          type: 'gcj02', // 使用国测局坐标系(微信推荐)
          enableHighAccuracy: true,
          timeout: 10000,
          success: async (res) => {
            const lat = res.latitude;
            const lng = res.longitude;
            const accuracy = res.accuracy;
            const altitude = res.altitude;
  
            try {
              const address = await this._reverseGeocodeUni(lat, lng);
              resolve({
                latitude: lat,
                longitude: lng,
                accuracy: Math.round(accuracy),
                altitude: altitude ? Math.round(altitude) : null,
                ...address,
                success: true
              });
            } catch (err) {
              resolve({
                latitude: lat,
                longitude: lng,
                accuracy: Math.round(accuracy),
                altitude: altitude ? Math.round(altitude) : null,
                country: '未知',
                province: '未知',
                city: '未知',
                district: '未知',
                street: '未知',
                warning: '地址解析失败: ' + (err.message || '网络错误')
              });
            }
          },
          fail: (err) => {
            let msg = '定位失败';
            if (err.errMsg.includes('auth deny')) {
              msg = '未授权定位,请在设置中开启位置权限';
            } else if (err.errMsg.includes('timeout')) {
              msg = '定位超时';
            } else if (err.errMsg.includes('fail')) {
              msg = '设备不支持或未开启GPS';
            }
            reject(new Error(msg));
          }
        });
      });
    },
  
    /**
     * H5 逆地理编码(模拟实现)
     * ⚠️ 实际项目请替换为真实 API:高德、腾讯地图等
     */
    _reverseGeocodeH5(lat, lng) {
      return new Promise((resolve, reject) => {
        // 模拟不同区域返回不同地址(随机)
        const mockAddresses = [
          { country: "中国", province: "广东省", city: "深圳市", district: "南山区", street: "科技南一路" },
          { country: "中国", province: "北京市", city: "北京市", district: "海淀区", street: "中关村大街" },
          { country: "中国", province: "上海市", city: "上海市", district: "浦东新区", street: "张江路" },
          { country: "中国", province: "浙江省", city: "杭州市", district: "西湖区", street: "文三路" },
          { country: "中国", province: "江苏省", city: "南京市", district: "鼓楼区", street: "中山北路" }
        ];
  
        // 模拟网络延迟
        setTimeout(() => {
          const randomIndex = Math.floor(Math.random() * mockAddresses.length);
          resolve(mockAddresses[randomIndex]);
        }, 800);
      });
    },
  
    /**
     * 小程序/App 逆地理编码(模拟)
     * ⚠️ 建议接入真实服务:
     * 腾讯地图:https://apis.map.qq.com/ws/geocoder/v1/
     * 高德地图:https://restapi.amap.com/v3/geocode/regeo
     */
    _reverseGeocodeUni(lat, lng) {
      return new Promise((resolve, reject) => {
        const mockAddresses = [
          { country: "中国", province: "广东省", city: "广州市", district: "天河区", street: "科韵路" },
          { country: "中国", province: "四川省", city: "成都市", district: "武侯区", street: "天府大道" },
          { country: "中国", province: "湖北省", city: "武汉市", district: "洪山区", street: "光谷大道" }
        ];
  
        setTimeout(() => {
          const randomIndex = Math.floor(Math.random() * mockAddresses.length);
          resolve(mockAddresses[randomIndex]);
        }, 1000);
      });
    }
  };

使用 

<!-- pages/index/index.vue -->

<template>

  <view class="container">

    <button @click="getLocation">获取位置</button>

    <p>经度:{{ lat }}</p>

    <p>纬度:{{ lng }}</p>

  </view>

</template>

<script>

import Location from "@/utils/amap-locationCur-web.js";

export default {

  data() {

    return {

      location: null,

      lat:'',

      lng:''

    };

  },

  methods: {

    async getLocation() {

      const { lat, lng } = await Location.getLocation();

      console.log(lat, lng);

      this.lat = lat

      this.lng = lng

    },

  },

};

</script>

<style>

.container {

  padding: 20px;

}

button {

  margin-bottom: 20px;

}

p {

  font-size: 14px;

  color: #333;

  line-height: 1.6;

}

</style>

<!-- pages/index/index.vue -->
<template>
  <view class="container">
    <button @click="getLocation">获取位置</button>

    <p>经度:{{ lat }}</p> 
    <p>纬度:{{ lng }}</p> 

  </view>
</template>

<script>
import Location from "@/utils/amap-locationCur-web.js";

export default {
  data() {
    return {
      location: null,
      lat:'',
      lng:''
    };
  },
  methods: {
    async getLocation() {
      const { lat, lng } = await Location.getLocation();
      console.log(lat, lng);
      this.lat = lat
      this.lng = lng
    },
  },
};
</script>

<style>
.container {
  padding: 20px;
}
button {
  margin-bottom: 20px;
}
p {
  font-size: 14px;
  color: #333;
  line-height: 1.6;
}
</style>

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐