目录:
-
- 一、核心流程概览
- 二、实现步骤
-
- [Step 1:申请地图WebService API密钥](#Step 1:申请地图WebService API密钥)
- [Step 2:封装线路规划API调用](#Step 2:封装线路规划API调用)
- [Step 3:创建线路规划页面(输入起点终点)](#Step 3:创建线路规划页面(输入起点终点))
- [Step 4:在地图页渲染线路(WebView实现)](#Step 4:在地图页渲染线路(WebView实现))
- [Step 5:创建本地H5地图文件](#Step 5:创建本地H5地图文件)
- 三、关键功能解析
-
- [1. 高德线路规划API参数与返回值](#1. 高德线路规划API参数与返回值)
- [2. 线路渲染核心JS代码](#2. 线路渲染核心JS代码)
- [3. 距离与时间格式化](#3. 距离与时间格式化)
- 四、避坑指南
-
- [1. 地址转经纬度(坐标解析)](#1. 地址转经纬度(坐标解析))
- [2. 坐标系一致性](#2. 坐标系一致性)
- [3. WebView本地H5文件路径](#3. WebView本地H5文件路径)
- [4. API Key权限](#4. API Key权限)
- 五、效果对比
- 六、完整项目结构
一、核心流程概览

二、实现步骤
Step 1:申请地图WebService API密钥
以 高德地图 为例(百度地图流程类似):
登录 高德开放平台 → 创建应用 → 添加 "Web服务" 类型Key,获取 API Key(需记录)。
开通 "路径规划" 服务(免费额度满足开发需求)。
Step 2:封装线路规划API调用
创建 RoutePlanService.ets,调用高德地图 驾车路线规划接口(支持起点终点经纬度/地址):
typescript
// services/RoutePlanService.ets
import http from '@ohos.net.http';
import { BusinessError } from '@ohos.base';
export class RoutePlanService {
private apiKey: string = '你的高德WebService API Key'; // 替换为实际Key
private driveRouteUrl: string = 'https://restapi.amap.com/v3/direction/driving'; // 驾车路线接口
/**
* 规划驾车路线(支持地址或经纬度)
* @param origin 起点(格式:"经度,纬度" 或 "地址")
* @param destination 终点(格式同上)
* @returns 线路数据 { path: 经纬度数组, distance: 距离(米), duration: 时间(秒) }
*/
async planDriveRoute(origin: string, destination: string): Promise<{
path: Array<{ longitude: number; latitude: number }>; // 线路经纬度数组
distance: number; // 总距离(米)
duration: number; // 总时间(秒)
}> {
return new Promise((resolve, reject) => {
// 1. 构建请求参数
const params = new Map<string, string>();
params.set('key', this.apiKey);
params.set('origin', origin); // 起点(如"113.3245,23.1022"或"广州市广州塔")
params.set('destination', destination); // 终点(同上)
params.set('strategy', '0'); // 路线策略:0=最快路线
// 2. 拼接请求URL
const queryString = Array.from(params.entries())
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
.join('&');
const requestUrl = `${this.driveRouteUrl}?${queryString}`;
// 3. 发起HTTP GET请求
let httpRequest = http.createHttp();
httpRequest.request(
requestUrl,
{ method: http.RequestMethod.GET },
(err: BusinessError, data: http.HttpResponse) => {
httpRequest.destroy(); // 销毁请求实例
if (err) {
reject(`路线规划失败: ${err.message}`);
return;
}
// 4. 解析返回数据(高德驾车路线接口格式)
if (data.responseCode === 200) {
const result = JSON.parse(data.result as string);
if (result.status === '1' && result.route && result.route.paths.length > 0) {
const pathData = result.route.paths[0]; // 取第一条路线
// 解析线路经纬度(高德返回格式:"经度,纬度;经度,纬度;...")
const pathArray = pathData.polyline.split(';').map((point: string) => {
const [lng, lat] = point.split(',').map(Number);
return { longitude: lng, latitude: lat };
});
resolve({
path: pathArray,
distance: Number(pathData.distance), // 距离(米)
duration: Math.ceil(Number(pathData.duration)) // 时间(秒)
});
} else {
reject(`路线规划无结果: ${result.info || '未知错误'}`);
}
} else {
reject(`HTTP错误: ${data.responseCode}`);
}
}
);
});
}
}
Step 3:创建线路规划页面(输入起点终点)
创建 RoutePlanPage.ets,实现用户输入起点终点并触发线路规划:
typescript
// pages/RoutePlanPage.ets
import { RoutePlanService } from '../services/RoutePlanService';
import router from '@ohos.router';
import promptAction from '@ohos.promptAction';
@Entry
@Component
struct RoutePlanPage {
@State origin: string = ''; // 起点
@State destination: string = ''; // 终点
private routeService: RoutePlanService = new RoutePlanService();
build() {
Column() {
// 1. 输入框(起点+终点)
Column() {
TextInput({ placeholder: '请输入起点(地址或位置)' })
.width('90%')
.height(45)
.margin(5)
.padding(10)
.backgroundColor('#FFFFFF')
.borderRadius(5);
TextInput({ placeholder: '请输入终点(地址或位置)' })
.width('90%')
.height(45)
.margin(5)
.padding(10)
.backgroundColor('#FFFFFF')
.borderRadius(5);
Button('规划路线')
.width('90%')
.height(45)
.margin(10)
.backgroundColor('#007AFF')
.onClick(async () => {
if (!this.origin || !this.destination) {
promptAction.showToast({ message: '请输入起点和终点' });
return;
}
// 2. 调用线路规划API并跳转地图页
try {
const routeData = await this.routeService.planDriveRoute(this.origin, this.destination);
// 跳转到地图页并传递线路数据
router.pushUrl({
url: 'pages/MapRoutePage',
params: { routeData: routeData }
});
} catch (err) {
promptAction.showToast({ message: `规划失败: ${err.message}` });
}
});
}
.width('100%')
.padding(10)
.backgroundColor('#F5F5F5');
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5');
}
}
Step 4:在地图页渲染线路(WebView实现)
创建 MapRoutePage.ets,通过 WebView加载高德H5地图 并渲染线路:
typescript
// pages/MapRoutePage.ets
import webview from '@ohos.web.webview';
import router from '@ohos.router';
@Entry
@Component
struct MapRoutePage {
private webController: webview.WebviewController = new webview.WebviewController();
private routeData: any = null; // 从路由获取的线路数据
aboutToAppear() {
// 获取从规划页传递的线路数据
this.routeData = router.getParams()?.routeData;
if (!this.routeData) {
router.back(); // 无数据时返回上一页
return;
}
}
build() {
Column() {
// 1. 线路信息(距离+时间)
Row() {
Column() {
Text(`距离: ${(this.routeData.distance / 1000).toFixed(2)} 公里`)
.fontSize(16)
.color('#333333');
Text(`时间: ${Math.ceil(this.routeData.duration / 60)} 分钟`)
.fontSize(16)
.color('#333333')
.margin({ top: 5 });
}
.width('100%')
.padding(15)
.backgroundColor('#FFFFFF');
}
.borderBottom({ width: 0.5, color: '#EEEEEE' });
// 2. WebView地图(渲染线路)
Web({
src: $rawfile('map_route.html'), // 本地H5地图文件(需提前准备)
controller: this.webController
})
.width('100%')
.height('85%')
.onPageEnd(() => {
// 地图加载完成后,调用JS渲染线路
this.renderRouteOnMap();
});
}
.width('100%')
.height('100%');
}
/**
* 调用H5地图的JS方法,渲染线路
*/
private renderRouteOnMap() {
if (!this.routeData) return;
// 1. 转换线路数据为JS数组格式
const pathArray = this.routeData.path.map((p: any) => `[${p.longitude}, ${p.latitude}]`).join(',');
// 2. 构造JS代码(调用高德地图API绘制线路)
const jsCode = `
// 初始化地图(若未初始化)
if (!window.map) {
window.map = new AMap.Map('mapContainer', {
zoom: 14,
center: [${this.routeData.path[0].longitude}, ${this.routeData.path[0].latitude}] // 起点为中心
});
}
// 绘制线路
const path = [${pathArray}]; // 线路经纬度数组
new AMap.Polyline({
path: path,
strokeColor: '#0066FF', // 线路颜色(蓝色)
strokeWeight: 6, // 线路宽度
strokeOpacity: 0.8, // 透明度
map: window.map
});
// 添加起点终点标记
new AMap.Marker({ position: path[0], map: window.map, icon: '/start.png' }); // 起点标记
new AMap.Marker({ position: path[path.length-1], map: window.map, icon: '/end.png' }); // 终点标记
// 调整地图视野以显示完整线路
window.map.setFitView();
`;
// 3. 在WebView中执行JS代码
this.webController.executeJs({
script: jsCode,
callback: (result) => {
if (result === null) {
console.error('线路渲染JS执行失败');
}
}
});
}
}
Step 5:创建本地H5地图文件
在 main/resources/rawfile 目录下创建 map_route.html(H5地图容器,加载高德地图JS API):
typescript
<!-- rawfile/map_route.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>线路规划地图</title>
<!-- 引入高德地图JS API(需替换为你的Web端Key) -->
<script src="https://webapi.amap.com/maps?v=2.0&key=你的高德Web端API Key"></script>
<style>
body, html { width: 100%; height: 100%; margin: 0; }
#mapContainer { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="mapContainer"></div> <!-- 地图容器 -->
</body>
</html>
三、关键功能解析
1. 高德线路规划API参数与返回值
核心参数:
- origin:起点(支持经纬度 113.3245,23.1022 或地址 广州市广州塔)。
- destination:终点(同上)。
- strategy:路线策略(0=最快路线,1=最短路线,3=躲避拥堵)。
返回数据(简化):
typescript
{
"status": "1",
"route": {
"paths": [
{
"polyline": "113.3245,23.1022;113.3255,23.1032;...", // 线路经纬度字符串(分号分隔)
"distance": "14085", // 距离(米)
"duration": "1140" // 时间(秒)
}
]
}
}
2. 线路渲染核心JS代码
在H5地图中,通过高德地图JS API绘制线路:
- Polyline组件:用于绘制折线,path 参数传入经纬度数组。
- Marker组件:添加起点终点标记(可自定义图标)。
- setFitView():自动调整地图视野,确保完整显示线路。
3. 距离与时间格式化
- 将API返回的 距离(米) 转换为公里:distance / 1000。
- 将 时间(秒) 转换为分钟:Math.ceil(duration / 60)。
四、避坑指南
1. 地址转经纬度(坐标解析)
若用户输入的是地址(如"广州塔"),需先调用 地理编码API 转换为经纬度:
typescript
// 地理编码接口(高德):https://restapi.amap.com/v3/geocode/geo
// 将地址转换为经纬度:"广州市广州塔" → "113.330943,23.113406"
2. 坐标系一致性
高德WebService API返回的是 GCJ02坐标系(火星坐标),H5地图JS API默认使用GCJ02,无需转换。若使用其他坐标系地图(如WGS84),需用 coordtransform 库转换。
3. WebView本地H5文件路径
H5文件需放在 main/resources/rawfile 目录,加载路径为 $rawfile('map_route.html'),确保WebView能正确访问。
4. API Key权限
- WebService Key:用于后端接口调用(如 RoutePlanService)。
- Web端JS Key:用于H5地图加载(map_route.html 中的高德JS API)。 两者需分别申请,不可混用。
五、效果对比
- 输入起点终点:用户输入"广州塔"和"广州东站"。
- 线路规划结果:API返回距离 14085米(14.085公里),时间 1140秒(19分钟)。
- 地图渲染:WebView中显示蓝色线路,起点绿色标记,终点红色标记,顶部显示距离和时间(与截图效果一致)。
六、完整项目结构

总结:
实现乘客输入起点终点后展示线路规划图的核心步骤为:
- 输入起点终点:通过TextInput获取用户输入。
- 调用线路规划API:使用高德WebService接口计算路线,获取经纬度数组、距离、时间。
- WebView渲染线路:通过H5地图JS API绘制折线、标记点,显示完整路线。
- 展示线路信息:格式化距离和时间并显示在页面顶部。
此方案低成本实现了截图中的线路规划功能,依赖地图WebService API和WebView,无需集成复杂的原生地图SDK。