關于作者
白曉明
寧夏圖爾科技有限公司董事長兼CEO、堅果派聯合創始人
華為HDE、潤和軟件HiHope社區專家、鴻蒙KOL、倉頡KOL
華為開發者學堂/51CTO學堂/CSDN學堂認證講師
開放原子開源基金會2023開源貢獻之星
OpenHarmony三方庫貢獻者
公眾號:開源開發者新視界(openwatcher)
在先前的環節中,我們所獲取到的位置信息是以經緯度的方式來呈現。不可否認,這種呈現方式在描述位置時具有極高的準確性,能夠精確地定位到地球的每一個點。然而,不得不承認的是,對于普通用戶而言,經緯度的表述形式顯示得過于專業和晦澀,缺乏直觀性和易理解性,確實不夠友好。
而HarmonyOS的位置服務(Location Kit)則猶如一位貼心的助手,為開發者提供了地理編碼轉化和逆地理編碼轉化這兩種極為實用的能力。其中,地理編碼就像是一個信息豐富的寶藏,它包含了多個屬性來對位置進行細致入微的描述。比如,它涵蓋了國家這個宏觀層面的標識,讓我們能夠快速確定位置所在的大區域;還有行政區劃,進一步明確了具體的地區范圍;街道的描述則讓我們對周邊環境有了更清晰的認知;門牌號更是精準地指向了具體的地點;而地址描述則以一種更為通俗易懂的方式將所有這些信息整合起來,為用戶提供一個全面而直觀的位置表達。這樣豐富多樣的信息呈現方式,無疑更加便于用戶理解和把握自己所處的位置,無論是在日常的出行導航中,還是在社交應用里與朋友分享位置,都能讓用戶輕松便捷地知曉自己的具體方位,為我們的數字生活帶來更多的便利和舒適體驗。
查看地理編碼與逆地理編碼服務是否可用
首先,開發者在進行操作時,需要優先調用isGeoServiceAvailable
方法來查詢地理編碼與逆地理編碼服務的可用性。這一步驟至關重要,因為只有當確定服務可用的情況下,才能夠進行后續的編碼轉化操作。如果經過查詢發現服務不可用,那么就意味著該設備并不具備地理編碼與逆地理編碼轉化能力。這種情況下,開發者務必不要使用相關接口,以免引起不必要的錯誤或者異常情況,從而確保應用程序的穩定性。
let isAvailable = geoLocationManager.isGeocoderAvailable();
把坐標轉化為地理位置信息
在實際應用中,我們可以通過調用getCurrentLocation()
函數獲取當前位置,也可以使用on('locationChange')
方法進行位置變化訂閱。然而,通過這兩種方式所獲取到的位置信息都是以坐標形式呈現出來的,對于普通用戶而言,這種坐標形式的位置信息可能會顯得比較抽象且難以理解。
為了能夠讓用戶更加直觀地理解位置信息,開發者可以調用getAddressesFromLocation
方法,該方法能夠將坐標形式的位置信息轉化為地理位置信息。比如國家信息、行政區、城市信息、區/縣信息、路名等等。具體位置信息如以下類所示:
/**
* 地理編碼地址信息
*/
export interface GeoAddress {
/**
* 緯度信息,正值表示北緯,負值表示南緯。
* 取值范圍為[-90, 90],僅支持WGS84坐標系。
*/
latitude?: number;
/**
* 經度信息,正值表示東經,負值表示西經。
* 取值范圍為[-180, 180],僅支持WGS84坐標系。
*/
longitude?: number;
/**
* 位置描述信息的語言。
* zh:中文;en:英文。
*/
locale?: string;
/**
* 詳細地址信息。
*/
placeName?: string;
/**
* 國家碼信息。
*/
countryCode?: string;
/**
* 國家信息。
*/
countryName?: string;
/**
* 一級行政區,一般是省/州。
*/
administrativeArea?: string;
/**
* 二級行政區,一般是市。
*/
subAdministrativeArea?: string;
/**
* 城市信息,一般是市。
*/
locality?: string;
/**
* 子城市信息,一般是區/縣。
*/
subLocality?: string;
/**
* 路名信息。
*/
roadName?: string;
/**
* 子路名信息。
*/
subRoadName?: string;
/**
* 門牌號信息。
*/
premises?: string;
/**
* 郵政編碼信息。
*/
postalCode?: string;
/**
* 聯系方式信息。
*/
phoneNumber?: string;
/**
* 位置信息附件的網址信息。
*/
addressUrl?: string;
/**
* 附加的描述信息。
* 目前包含城市編碼cityCode和區劃編碼adminCode。
*/
descriptions?: Array< string >;
/**
* 附加的描述信息數量。
* 取值大于等于0,推薦該值小于10。
*/
descriptionsSize?: number;
}
以轉化當前坐標為例,代碼如下所示:
/**
* 逆地理編碼請求參數
*/
export interface ReverseGeoCodeRequest {
/**
* 指定位置描述信息的語言。
* zh:中文;en:英文。
*/
locale?: string;
/**
* 限制查詢結果在指定的國家區,采用ISO3166-1 alpha-2。
* CN代表中國。
*/
country?: string;
/**
* 緯度信息。
*/
latitude: number;
/**
* 經度信息。
*/
longitude: number;
/**
* 指定返回位置信息的最大個數。
*/
maxItems?: number;
}
/**
* 坐標轉化為地理位置信息
* @param latitude
* @param longitude
* @param maxItems
* @returns
*/
static async getAddressesFromLocation(latitude: number,
longitude: number, maxItems: number = 1): Promise< geoLocationManager.GeoAddress[] | undefined > {
const request: geoLocationManager.ReverseGeoCodeRequest = {
locale: "zh",
country: "CN",
latitude,
longitude,
maxItems
};
let location: geoLocationManager.GeoAddress[] | undefined = undefined;
try {
location = await geoLocationManager.getAddressesFromLocation(request);
console.info(`[AppLogger]坐標轉化為地理位置信息:${JSON.stringify(location)}`);
} catch (error) {
const err = error as BusinessError;
console.error(`[AppLogger]坐標轉化為地理位置信息異常:${JSON.stringify(err)}`);
}
return location;
}
Button('坐標轉化為地理位置信息')
.onClick(async () = > {
this.location = await LocationUtil.getSingleLocationRequest(geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED);
if (this.location !== undefined) {
this.locationArr = await LocationUtil.getAddressesFromLocation(this.location?.latitude, this.location?.longitude);
}
})
把地理位置信息轉化為坐標
在導航類App的實際使用場景中,當用戶進行位置搜索時,通常會輸入具體的位置信息,比如某個商場的名稱、某條街道的地址或者某個景點的具體描述等。但是,對于地圖的顯示而言,它所需要的是精確的位置坐標信息,只有這樣才能夠準確地在地圖上進行標注和展示。
在這種情況下,為了實現從用戶輸入的位置描述到地圖所需的坐標信息的轉化,開發者可以調用getAddressesFromLocationName
方法。這個方法就像是一座橋梁,能夠將用戶輸入的直觀的位置描述轉化為地圖能夠識別和使用的位置坐標。通過這樣的轉化,不僅可以滿足地圖顯示的需求,還能夠為用戶提供更加準確和便捷的導航服務,讓用戶能夠更加輕松地找到自己想要達到的目的地。
以轉化用戶輸入地理位置為例,代碼如下所示:
/**
* 地理編碼請求參數
*/
export interface GeoCodeRequest {
/**
* 位置描述信息的語言。
* zh:中文;en:英文。
*/
locale?: string;
/**
* 限制查詢結果在指定的國家區,采用ISO3166-1 alpha-2。
* CN代表中國。
*/
country?: string;
/**
* 位置信息描述。
*/
description: string;
/**
* 返回結果信息的最大個數。
*/
maxItems?: number;
/**
* 最小緯度信息。
*/
minLatitude?: number;
/**
* 最小經度信息。
*/
minLongitude?: number;
/**
* 最大緯度信息。
*/
maxLatitude?: number;
/**
* 最大經度信息。
*/
maxLongitude?: number;
}
/**
* 地理位置轉化為坐標信息
* @param description
* @param maxItems
* @returns
*/
static async getAddressesFromLocationName(description: string,
maxItems: number = 1): Promise< geoLocationManager.GeoAddress[] | undefined > {
const request: geoLocationManager.GeoCodeRequest = {
description,
maxItems
};
let location: geoLocationManager.GeoAddress[] | undefined = undefined;
try {
location = await geoLocationManager.getAddressesFromLocationName(request);
console.info(`[AppLogger]地理位置轉化為坐標信息:${JSON.stringify(location)}`);
} catch (error) {
const err = error as BusinessError;
console.error(`[AppLogger]地理位置轉化為坐標信息異常:${JSON.stringify(err)}`);
}
return location;
}
TextInput({ placeholder: "請輸入具體的位置信息..." })
.onChange((value: string) = > {
this.val = value;
})
Button('坐標轉化為地理位置信息')
.onClick(async () = > {
if (LocationUtil.usedGeocoderAvailable()) {
this.locationArr = await LocationUtil.getAddressesFromLocationName(this.val, 5);
}
})
使用ForEach
渲染列表數據
List() {
ForEach(this.locationArr, (item: geoLocationManager.GeoAddress) = > {
ListItem() {
Column({ space: 8 }) {
Text(item.placeName)
.fontSize(16)
Text(`坐標:[${item.latitude}, ${item.longitude}]`)
.fontSize(12)
Text(`${item.countryName} ${item.administrativeArea} ${item.locality} ${item.subLocality} ${item.roadName} ${item.subRoadName}`)
.fontSize(12)
}
.width('100%')
.padding(12)
.backgroundColor(0xF1F3F5)
.borderRadius(8)
.justifyContent(FlexAlign.Start)
}
})
}
.width('90%')
.divider({
strokeWidth: 4,
color: 0xFFFFFF
})
審核編輯 黃宇
-
位置服務
+關注
關注
0文章
5瀏覽量
2056 -
HarmonyOS
+關注
關注
79文章
1967瀏覽量
30033
發布評論請先 登錄
相關推薦
評論