需要用到第三方地图的逆解析,反推出当前城市。我这里用的是腾讯地图api,需要准备key

官网链接:  腾讯位置服务 - 立足生态,连接未来

注意:下面代码的地址链接 key 得换成你自己的key,别用我的,用我的你会报错。

例如:url: '/map-api/ws/geocoder/v1/?location=28.23529,112.93134&key=AVSBZ-6BILR-K2EWT-WCIAT-DBFFF-XXXXX&get_poi=1',

这里替换成你的key,总共有三个地方,请注意一下。

// 自动获取用户定位
export async function autoGetLocation() {
	try {
		// #ifdef MP-WEIXIN
		// 检查定位权限
		const authResult = await uni.getSetting()
		if (!authResult.authSetting['scope.userLocation']) {
			// 没有定位权限,请求权限
			const authRes = await uni.authorize({
				scope: 'scope.userLocation'
			})
		}
		// #endif

		// 获取定位
		const location = await new Promise((resolve, reject) => {
			uni.getLocation({
				type: 'gcj02',
				success: (res) => resolve(res),
				fail: (err) => reject(err)
			})
		})
		// 根据平台使用不同的逆地理编码方案
		let cityName = await getCityByLocation(location.latitude, location.longitude);
		return {
			latitude: location.latitude,
			longitude: location.longitude,
			cityName
		}
	} catch (error) {
		console.error('自动定位失败:', error)
		uni.showToast({
			title: "无法获取当前位置,请手动选择城市",
			icon: "none",
			duration: 3000
		});
		return {
			latitude: '',
			longitude: '',
			cityname: ''
		}
	}
}
// 测试代理接口是否正常工作
async function testProxyConnection() {
	try {
		const response = await uni.request({
			url: '/map-api/ws/geocoder/v1/?location=28.23529,112.93134&key=AVSBZ-6BILR-K2EWT-WCIAT-DBFFF-XXXXX&get_poi=1',
			method: 'GET',
			timeout: 5000
		})
		return true
	} catch (error) {
		return false
	}
}
// 根据坐标获取城市信息
async function getCityByLocation(lat, lng) {
	try {
		// #ifdef H5
		// H5环境:使用代理接口调用腾讯地图API
		// 先测试代理连接
		const proxyWorking = await testProxyConnection()
		if (proxyWorking) {
			try {
				// 使用代理接口调用腾讯地图逆地理编码API
				const response = await new Promise((resolve, reject) => {
					uni.request({
						url: `/map-api/ws/geocoder/v1/?location=${lat},${lng}&key=AVSBZ-6BILR-K2EWT-WCIAT-DBFFF-XXXXXX&get_poi=1`,
						method: 'GET',
						timeout: 10000,
						success: (res) => resolve(res),
						fail: (err) => reject(err)
					})
				})
				if (response.data && response.data.status === 0 && response.data.result) {
					const addressComponent = response.data.result.address_component
					return addressComponent.city || addressComponent.district || '长沙市'
				} else {
					// 降级方案:使用坐标范围判断城市
					return getCityByCoordinates(lat, lng)
				}
			} catch (error) {
				console.error('H5代理定位失败:', error)
				// 最终降级方案:使用坐标范围判断城市
				return getCityByCoordinates(lat, lng)
			}
		} else {
			// 代理不可用,直接使用坐标判断城市
			return getCityByCoordinates(lat, lng)
		}
		// #endif

		// #ifdef MP-WEIXIN
		// 小程序环境:直接调用腾讯地图API
		const response = await new Promise((resolve, reject) => {
			uni.request({
				url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=AVSBZ-6BILR-K2EWT-WCIAT-DBFFF-XXXXX&get_poi=1`,
				method: 'GET',
				success: (res) => resolve(res),
				fail: (err) => reject(err)
			})
		})

		if (response.data && response.data.status === 0 && response.data.result) {
			const addressComponent = response.data.result.address_component
			// console.log('定位成功,当前城市:', addressComponent)
			return addressComponent.city || addressComponent.district || '长沙市'
		} else {
			return '长沙市'
		}
		// #endif

	} catch (error) {
		console.error('获取城市信息失败:', error)
		return '长沙市'
	}
}
// 根据坐标判断城市(简单的地理范围判断)
const getCityByCoordinates = (lat, lng) => {
	// 主要城市的经纬度范围(简化版)
	const cityRanges = [{
			name: '北京市',
			latMin: 39.4,
			latMax: 41.0,
			lngMin: 115.7,
			lngMax: 117.4
		},
		{
			name: '上海市',
			latMin: 30.7,
			latMax: 31.9,
			lngMin: 120.9,
			lngMax: 122.1
		},
		{
			name: '广州市',
			latMin: 22.7,
			latMax: 23.8,
			lngMin: 113.0,
			lngMax: 114.0
		},
		{
			name: '深圳市',
			latMin: 22.4,
			latMax: 22.9,
			lngMin: 113.7,
			lngMax: 114.6
		},
		{
			name: '杭州市',
			latMin: 30.0,
			latMax: 30.6,
			lngMin: 119.8,
			lngMax: 120.6
		},
		{
			name: '长沙市',
			latMin: 28.0,
			latMax: 28.5,
			lngMin: 112.8,
			lngMax: 113.2
		},
		{
			name: '武汉市',
			latMin: 30.3,
			latMax: 30.8,
			lngMin: 114.0,
			lngMax: 114.6
		},
		{
			name: '成都市',
			latMin: 30.4,
			latMax: 30.9,
			lngMin: 103.8,
			lngMax: 104.3
		}
	]
	for (const city of cityRanges) {
		if (lat >= city.latMin && lat <= city.latMax &&
			lng >= city.lngMin && lng <= city.lngMax) {
			return city.name
		}
	}
	// 默认返回长沙市
	return '长沙市'
}

在使用第三方地图api,可能会造成跨域问题,所以需要配置代理

// 腾讯地图API代理
				'/map-api': {
					target: 'https://apis.map.qq.com',
					changeOrigin: true,
					rewrite: (p) => p.replace(/^\/map-api/, ''),
					headers: {
						'Referer': 'https://apis.map.qq.com',
						'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
					},
					timeout: 10000,
					configure: (proxy, options) => {
						proxy.on('error', (err, req, res) => {
							console.log('地图API代理错误:', err);
						});
						proxy.on('proxyReq', (proxyReq, req, res) => {
							console.log('发送地图API请求:', req.url);
						});
						proxy.on('proxyRes', (proxyRes, req, res) => {
							console.log('收到地图API响应:', proxyRes.statusCode);
						});
					}
				}

还需要在 manifest.json  文件中进行配置

"mp-weixin": {
    "permission": {
			"scope.userLocation": {
				"desc": "你的位置信息将用于小程序位置接口的效果展示"
			}
		},
		"requiredPrivateInfos": ["chooseAddress", "getLocation", "chooseLocation"]
}

"h5": {   
     "permission": {
			"geolocation": {
				"description": "获取你的位置信息用于展示当前城市"
			}
		},
		"sdkConfigs": {
			"maps": {
				"qqmap": {
					"key": "AVSBZ-6BILR-K2EWT-WCIAT-DBFFF-XXXXT"
				}
			}
		}
}

最后注意一下,如果没成功,你看下这里是否有这些内容,这些都是关于定位相关的,需要配置上

"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_BACKGROUND_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",

更多推荐