鸿蒙 地理编码:正地理编码与逆地理编码
开发中,定位功能除了获取经纬度坐标外,常常还需要将坐标转换为用户可读的位置描述(如国家、城市、街道等)。系统提供了正地理编码和逆地理编码两种转化能力。
一、地理编码
使用经纬度坐标描述一个位置非常准确,但是并不直观,面向用户表达并不友好。系统提供了以下两种转化能力:
| 能力 | 说明 | 输入 | 输出 |
|---|---|---|---|
| 正地理编码 | 将地理编码转化为具体经纬度坐标 | 地址描述(如"上海市浦东新区xx路xx号") | 经纬度坐标 |
| 逆地理编码 | 将具体的经纬度坐标转化为地理编码 | 经纬度坐标 | 国家、行政区划、街道、门牌号、地址描述等 |
地理编码包含的信息
逆地理编码返回的GeoAddress包含多个属性,便于用户理解:
| 信息项 | 说明 |
|---|---|
| 国家 | 国家名称 |
| 行政区划 | 省/市/区 |
| 街道 | 街道名称 |
| 门牌号 | 具体门牌号 |
| 地址描述 | 完整地址描述 |
二、核心接口
| 接口 | 功能描述 |
|---|---|
isGeocoderAvailable() | 判断地理编码与逆地理编码服务是否可用 |
getAddressesFromLocation(request, callback) | 逆地理编码:将坐标转换为地理描述 |
getAddressesFromLocationName(request, callback) | 正地理编码:将地理描述转换为具体坐标 |
三、开发步骤
3.1 导入模块
import { geoLocationManager } from '@kit.LocationKit';3.2 查询服务是否可用
重要:正地理编码与逆地理编码功能需要访问后端服务,请确保设备联网,以进行信息获取。
try { let isAvailable = geoLocationManager.isGeocoderAvailable(); console.info('地理编码服务可用: ' + isAvailable); } catch (err) { console.error("errCode:" + JSON.stringify(err)); }注意:如果服务不可用,说明该设备不具备地理编码与逆地理编码能力,请勿使用相关接口。
3.3 逆地理编码:坐标 → 地址
将经纬度坐标转化为地理编码(即位置信息),获得匹配的GeoAddress列表。
请求参数(ReverseGeoCodeRequest):
| 参数 | 类型 | 说明 |
|---|---|---|
latitude | number | 纬度 |
longitude | number | 经度 |
maxItems | number | 返回的最大结果数 |
let reverseGeocodeRequest: geoLocationManager.ReverseGeoCodeRequest = { "latitude": 31.12, "longitude": 121.11, "maxItems": 1 }; try { geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest, (err, data) => { if (err) { console.error('getAddressesFromLocation err: ' + JSON.stringify(err)); } else { console.info('getAddressesFromLocation data: ' + JSON.stringify(data)); // data为GeoAddress数组,包含国家、行政区划、街道等信息 } }); } catch (err) { console.error("errCode:" + JSON.stringify(err)); }3.4 正地理编码:地址 → 坐标
将地理编码(即位置信息)转化为经纬度坐标。
请求参数(GeoCodeRequest):
| 参数 | 类型 | 说明 |
|---|---|---|
description | string | 地址描述(如"上海市浦东新区xx路xx号") |
maxItems | number | 返回的最大结果数 |
minLatitude | number | 可选,最小纬度(用于限定范围) |
minLongitude | number | 可选,最小经度 |
maxLatitude | number | 可选,最大纬度 |
maxLongitude | number | 可选,最大经度 |
let geocodeRequest: geoLocationManager.GeoCodeRequest = { "description": "北京市丰台区xx路xx号", "maxItems": 1 }; try { geoLocationManager.getAddressesFromLocationName(geocodeRequest, (err, data) => { if (err) { console.error('getAddressesFromLocationName err: ' + JSON.stringify(err)); } else { console.info('getAddressesFromLocationName data: ' + JSON.stringify(data)); // data为GeoAddress数组,包含纬度、经度等坐标信息 } }); } catch (err) { console.error("errCode:" + JSON.stringify(err)); }3.5 提高查询精度
如果需要查询的位置信息可能出现多地重名的情况,可以通过设置经纬度范围来限定查询区域,以高效地获取期望的准确结果。
let geocodeRequest: geoLocationManager.GeoCodeRequest = { "description": "南京路", "maxItems": 5, "minLatitude": 31.0, "minLongitude": 121.0, "maxLatitude": 31.5, "maxLongitude": 121.5 };四、完整示例
import { geoLocationManager } from '@kit.LocationKit'; import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component struct GeocodeDemo { @State latitude: string = ''; @State longitude: string = ''; @State address: string = ''; build() { Column() { // 逆地理编码:坐标转地址 Button('坐标转地址') .onClick(() => { this.reverseGeocode(); }) Text('纬度: ' + this.latitude) Text('经度: ' + this.longitude) Text('地址: ' + this.address) } .padding(20) } // 逆地理编码:坐标 → 地址 reverseGeocode() { // 检查服务是否可用 if (!geoLocationManager.isGeocoderAvailable()) { console.error('地理编码服务不可用'); return; } let request: geoLocationManager.ReverseGeoCodeRequest = { latitude: 31.12, longitude: 121.11, maxItems: 1 }; try { geoLocationManager.getAddressesFromLocation(request, (err, data) => { if (err) { console.error('逆地理编码失败: ' + JSON.stringify(err)); } else if (data && data.length > 0) { let addr = data[0]; this.latitude = addr.latitude?.toString() || ''; this.longitude = addr.longitude?.toString() || ''; this.address = addr.description || ''; console.info('逆地理编码成功: ' + JSON.stringify(addr)); } }); } catch (err) { console.error("逆地理编码异常: " + JSON.stringify(err)); } } // 正地理编码:地址 → 坐标 forwardGeocode() { if (!geoLocationManager.isGeocoderAvailable()) { console.error('地理编码服务不可用'); return; } let request: geoLocationManager.GeoCodeRequest = { description: "北京市丰台区石榴庄街道xxx号", maxItems: 1 }; try { geoLocationManager.getAddressesFromLocationName(request, (err, data) => { if (err) { console.error('正地理编码失败: ' + JSON.stringify(err)); } else if (data && data.length > 0) { let addr = data[0]; console.info('正地理编码成功: 纬度=' + addr.latitude + ', 经度=' + addr.longitude); } }); } catch (err) { console.error("正地理编码异常: " + JSON.stringify(err)); } } }五、注意事项
| 注意事项 | 说明 |
|---|---|
| 网络要求 | 正地理编码与逆地理编码功能需要访问后端服务,请确保设备联网 |
| 服务可用性 | 调用前应使用isGeocoderAvailable()检查服务是否可用 |
| 重名处理 | 对于可能多地重名的地址,建议设置经纬度范围以精确匹配 |
| 异步回调 | 两个转换接口均使用callback异步回调方式返回结果 |
