【高心星出品】
文章目錄
- 鴻蒙接入高德地圖實現POI搜索
- 運行結果:
- 準備地圖
- 編寫ArkUI布局來加載HTML地圖
鴻蒙接入高德地圖實現POI搜索
在當今數字化時代,地圖應用已成為移動設備中不可或缺的一部分。隨著鴻蒙系統的日益普及,如何在鴻蒙應用中接入高德地圖并實現POI(興趣點)檢索功能,成為了眾多開發者關注的焦點。本文將詳細介紹這一過程,幫助開發者快速上手,為用戶打造更優質的地圖體驗。
鴻蒙系統作為華為自主研發的分布式操作系統,具有高性能、低功耗等諸多優勢,為智能設備提供了強大的支持。而高德地圖憑借其豐富的數據資源、精準的定位功能以及多樣化的地圖服務,在國內地圖應用領域占據重要地位。將鴻蒙與高德地圖相結合,能夠充分發揮雙方的優勢,為用戶提供更加便捷、高效的地圖導航和POI檢索服務。
但是目前高德地圖API暫不支持HarmonyOS5.0版本,需要使用鴻蒙的Web組件加載JS版高德地圖。
運行結果:
準備地圖
首先需要注冊高德地圖開發者,創建應用:https://lbs.amap.com/api/javascript-api-v2/prerequisites
準備一個基礎地圖。
HTML代碼如下:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><metaname="viewport"content="initial-scale=1.0, user-scalable=no, width=device-width"/><title>HELLO,AMAP!</title><style>html,body,#container {width: 100%;height: 100%;}</style><style type="text/css">#panel {position: absolute;max-height: 90%;height:300px;overflow-y: auto;top: 50px;right: 10px;width: 180px;}.amap_lib_placeSearch .poibox .poi-title{font-size:12px;}.amap_lib_placeSearch .poibox .poi-info p{font-size:10px;}#search {position: absolute;background-color: transparent;max-height: 90%;overflow-y: auto;top: 20px;right: 10px;width: 180px;}#search_input{width:120px;}</style>
</head>
<body>
<div id="container"></div>
<div id="panel"></div>
<div id="search"><input id="search_input" type="text" placeholder="搜索地址"><input id="search_sub" type="submit" value="搜索" onclick="search()">
</div>
<script type="text/javascript">window._AMapSecurityConfig = {securityJsCode: "210560c7b915b95686d9baa8b12d5a83",};
</script>
<script src="https://webapi.amap.com/loader.js"></script>
<script type="text/javascript">var mapAMapLoader.load({key: "d7b81d72864f222e583d2283493cdd58", //申請好的Web端開發者 Key,調用 load 時必填version: "2.0", //指定要加載的 JS API 的版本,缺省時默認為 1.4.15}).then((AMap) => {map = new AMap.Map("container",{zoom:10,center: [118.832028,31.875796], //地圖中心點});//異步加載控件AMap.plugin('AMap.ToolBar',function(){var toolbar = new AMap.ToolBar(); //縮放工具條實例化map.addControl(toolbar); //添加控件});//異步加載控件AMap.plugin('AMap.Scale',function(){var scale = new AMap.Scale()map.addControl(scale); //添加控件});}).catch((e) => {console.error(e); //加載錯誤提示});function search(){// 獲取輸入框元素var inputElement = document.getElementById('search_input');// 獲取輸入框中的文本內容var searchText = inputElement.value;console.log(searchText); // 在控制臺輸出文本內容searchplace(searchText)}function searchplace(addr){AMap.plugin(["AMap.PlaceSearch"], function () {const placeSearch = new AMap.PlaceSearch({pageSize: 5, //單頁顯示結果條數pageIndex: 1, //頁碼
<!-- city: "江蘇", //興趣點城市-->
<!-- citylimit: true, //是否強制限制在設置的城市內搜索-->selectFirst:true,map: map, //展現結果的地圖實例panel: "panel", //參數值為你頁面定義容器的 id 值<div id="my-panel"></div>,結果列表將在此容器中進行展示。autoFitView: true, //是否自動調整地圖視野使繪制的 Marker 點都處于視口的可見范圍});placeSearch.on('selectChanged', function(e) {console.log(JSON.stringify(e.selected.data))postStringToApp(JSON.stringify(e.selected.data))});placeSearch.search(addr);});}//-------------------地圖展示很poi檢索js代碼----------------------------------//--------------------------------與arkts通信代碼--------------------------
var h5Port;
window.addEventListener('message', function(event) {if (event.data == 'initport') {if(event.ports[0] != null) {h5Port = event.ports[0]; // 1. 保存從ets側發送過來的端口h5Port.onmessage = function(event) {// 2. 接收ets側發送過來的消息.var result = event.data;console.log('arkts發來的消息: '+result)}h5Port.onmessageerror = (event) => {console.error(`發送了錯誤信息: ${event}`);};}}
})// 使用h5Port往ets側發送String類型的消息.
function postStringToApp(str) {if (h5Port) {h5Port.postMessage(str);} else {console.error("In html h5port is null, please init first");}
}</script>
</body>
</html>
除了展示地圖,還有與ArkTS通信的過程:
HTML網頁會接收到ArkTS第一次發送的端口號,通過該端口號建立通道,后面就可以通過該端口號收發消息。
var h5Port;
window.addEventListener('message', function(event) {if (event.data == 'initport') {if(event.ports[0] != null) {h5Port = event.ports[0]; // 1. 保存從ets側發送過來的端口h5Port.onmessage = function(event) {// 2. 接收ets側發送過來的消息.var result = event.data;console.log('arkts發來的消息: '+result)}h5Port.onmessageerror = (event) => {console.error(`發送了錯誤信息: ${event}`);};}}
})// 使用h5Port往ets側發送String類型的消息.
function postStringToApp(str) {if (h5Port) {h5Port.postMessage(str);} else {console.error("In html h5port is null, please init first");}
}
編寫ArkUI布局來加載HTML地圖
加入權限
由于加載的地圖需要使用網絡權限,需要早module.json5中加入INTENET權限。
"module": {'requestPermissions': [{"name": "ohos.permission.INTERNET"}],....
加載地圖
需要將離線的html地圖放入項目的rawfile資源中。
編寫ArkTS代碼
這里需要在web組件加載結束后,與離線html建立通道收發消息。
import { webview } from '@kit.ArkWeb';
import { Addr } from '../../model/Addr';@Entry
@Component
struct Index {@State message: string = 'Hello World';@State addrname:string=''@State addr:string=''private ports:webview.WebMessagePort[]=[]private port:webview.WebMessagePort|null=nullprivate controller:WebviewController=new webview.WebviewController()build() {Column(){Row({space:10}){Text('地點名稱:')TextInput({text:this.addrname}).enabled(false).layoutWeight(1)}.width('100%').padding(10)Row({space:10}){Text('詳細地址:')TextInput({text:this.addr}).enabled(false).layoutWeight(1)}.width('100%').padding(10)Web({src:$rawfile('poijiansuo.html'),controller:this.controller}).javaScriptAccess(true).imageAccess(true).zoomAccess(true).margin({top:10}).onPageEnd(()=>{// 創建web的通道端口號this.ports= this.controller.createWebMessagePorts()console.log('gxxt ',JSON.stringify(this.ports))// 將第二個端口號發送給html,做為html發送和接受arkts信息的端口號this.controller.postMessage('initport',[this.ports[1]],'*')//第一個端口號留給自己,作為發送和接受html信息的端口號this.port=this.ports[0]this.port.onMessageEventExt((result)=>{// 接受html的結果console.log('gxxt',JSON.stringify(result))let data= result.getString()let jsondata=JSON.parse(data) as Addrthis.addrname=jsondata.namethis.addr=jsondata.pname+jsondata.cityname+jsondata.adname+jsondata.address})})}.height('100%').width('100%')}
}
當從地圖搜索某個POI地點后,點擊列表中的搜索結果,就會將具體地址信息發送給ArkTS端,然后在鴻蒙端進行解析。
Addr接口
/***作者:gxx*時間:2025/2/21 16:43*功能:**/
export interface Addr {"id": string"name":string"type":string"location": number[],"address":string"tel":string"distance":string|null"shopinfo":string"website":string"pcode":string"citycode":string"adcode":string"postcode":string"pname":string"cityname":string"adname":string"email":string"photos": photos[]"entr_location": number[]"exit_location":string|null"groupbuy":boolean"discount":boolean"indoor_map":boolean"_idx":number"index":number
}
interface photos
{"title":string"url":string
}