map kit组件的使用 原创
前言
HarmonyOS NEXT版本的api11与之前我们常用的api9相比,确实增添了许多实用的api接口。目前对我来说,map kit是其中最为频繁利用的一个。在官方给出的案例中,关于地图功能的展示只是简单地绘制了一条折线,虽然基础但略显单调。
今天,我与大家分享一个关于使用HarmonyOS NEXT版本中的map kit API来实现的小案例。这个小案例只需输入起点和终点,就可以在地图上自动标记并生成一条清晰的导航路线,这个功能能够迅速为你提供直观的视觉参考。效果如下图展示
实现
绘制折现
绘制折线的逻辑在官方文档上确实有详细的说明,它主要是通过将一系列坐标点按顺序连接起来,形成一条在地图上可视化的路径。具体来说,当你想要在地图上标记一条导航路线时,你需要先获取到这条路线上的所有关键坐标点。然后把他们连接起来
let polylineOption: mapCommon.MapPolylineOptions = {
// 坐标点集合
points: [{longitude:118.78,latitude:31.975}, {longitude:118.78,latitude:31.982}, {longitude:118.79,latitude:31.985}],
clickable: true,
startCap: mapCommon.CapStyle.BUTT,
endCap: mapCommon.CapStyle.BUTT,
geodesic: false,
jointType: mapCommon.JointType.BEVEL,
visible: true,
width: 10,
zIndex: 10,
gradient: false
}
为了在地图上准确地绘制出导航路线,我们首先需要获取从起始点到终点的详细路线信息,这其中最关键的就是路线的坐标点集。这些坐标点集就像是构成路线的“骨架”,它们定义了路线的形状和走向。
但是在HarmonyOS NEXT版本的map kit中,特别是其navi(导航)相关的API里,为我们提供了获取这些坐标点集的便捷方法。通过这些API,我们可以轻松地请求从起始点到终点的最优路径,并获取到该路径上所有关键的坐标点。
在HarmonyOS NEXT版本的map kit中,navi API通常要求输入的起始点和终点是以坐标点(经纬度)的形式提供的,而不是直接输入地名或地址。这是因为坐标点能够更精确地定位地理位置,避免了地名或地址可能存在的模糊性或歧义性。
然而,在实际应用中,用户往往更习惯于输入地名或地址来指定起始点和终点。为了解决这个问题,我们需要在调用navi API之前,先将用户输入的地名或地址转换为对应的坐标点。
将地点转化为坐标点
这段逻辑实现了根据用户输入的地点名称,自动查询并返回该地点的精确坐标信息,这些坐标信息随后将被用于导航路线的搜索与规划。当用户在地图应用中输入他们想要前往的地点名称时,快速检索出与输入名称相匹配的地理位置坐标。一旦获取到这些坐标,它们就会被作为关键参数传递给导航模块,从而触发后续的路线计算与展示流程。
async search(place: string): Promise<mapCommon.LatLng> {
let params: site.SearchByTextParams = {
// 输入的地点信息
query: place,
// 搜索半径
radius: 10000,
// 输入语言
language: "en"
};
// 获取到的位置信息
const result: site.SearchByTextResult = await (site.searchByText(params));
// 因为是个简单的例子,所以只取第一个位置的信息
return result.sites![0].location as mapCommon.LatLng
}
根据起始坐标点获取折线坐标集
这段逻辑负责接收起始点和终点的坐标信息,并通过导航服务计算出导航路线的详细坐标点集。这些坐标点集随后被用于在地图上绘制出清晰的导航折线,以便用户能够直观地查看从起点到终点的路线走向。
// 获取导航路线
async navigation_directions(start: mapCommon.LatLng, end: mapCommon.LatLng) {
let params: navi.RouteParams = {
// 起始点坐标
origins: [
start
],
// 终点坐标
destination: end,
language: "zh_CN"
};
const result: navi.RouteResult = await (navi.getWalkingRoutes(params));
return result
}
将折线绘制在地图上
这一步就是将之前获取到的导航路线坐标点集通过编程代码实际应用到地图上,将这些坐标点按顺序连接起来,最终在地图界面上呈现出一条清晰可见的导航折线。
aboutToAppear() {
// 地图初始化参数
this.mapOptions = {
position: {
target: {
latitude: 31.98,
longitude: 118.78
},
zoom: 14
}
};
this.callback = async (err, mapController) => {
if (!err) {
this.mapController = mapController;
// 获取起始目标点和终点目标点
let start = (await this.search(this.start))
let end = (await this.search(this.end))
// 获取导航路线
let nav: navi.RouteResult = (await this.navigation_directions(start, end))
let route = nav.routes[0].overviewPolyline as mapCommon.LatLng[]
// polyline初始化参数
let polylineOption: mapCommon.MapPolylineOptions = {
points: route,
clickable: true,
startCap: mapCommon.CapStyle.BUTT,
endCap: mapCommon.CapStyle.BUTT,
geodesic: false,
jointType: mapCommon.JointType.BEVEL,
visible: true,
width: 10,
zIndex: 10,
gradient: false
}
// 创建polyline
this.mapPolyline = await this.mapController.addPolyline(polylineOption);
}
};
}
完整代码
最后附上完整的案例代码
这个初始页面,专门设计用来让用户输入他们的出发地点和目的地点。在这个页面上,可以看到两个输入框,一个用于填写初始地,即他们旅程的起点;另一个则用于填写到达地,即他们期望抵达的终点。
import { MapComponent, mapCommon, map } from '@kit.MapKit';
import { AsyncCallback } from '@ohos.base';
import { router } from '@kit.ArkUI';
@Entry
@Component
struct HuaweiMapDemo {
@State start: string = ""
@State end: string = ""
build() {
Column() {
Column() {
Column() {
Text("起始点")
TextInput()
.onChange((value: string) => {
this.start = value
})
}
Column() {
Text("到达点")
TextInput()
.onChange((value: string) => {
this.end = value
})
}
}
.width("100%")
Button("导航")
.onClick(() => {
router.pushUrl({
url: "pages/Nav",
params: {
start: this.start,
end: this.end
}
})
})
}
.size({ width: "100%", height: "100%" })
.justifyContent(FlexAlign.SpaceEvenly)
}
}
导航页,负责显示我们刚刚生成的折现,起到一个最短路线的效果