基于天地图的 Java 路径规划工具类封装(驾车/步行推荐路线)
·
1. 背景
在做水利、防汛、应急管理、智能交通等系统时,经常会涉及 路径规划 的需求。比如:
-
村庄转移到安置点的最优路线
-
防汛物资的运输路线
-
应急抢险人员的行进路线
天地图官方提供了 驾车/步行路径规划 API,返回的是 XML 格式数据。但直接解析 XML 比较麻烦,所以我写了一个 Java 工具类 TiandituRouteUtils,帮大家快速获取推荐路线。
2. 天地图 API 简介
-
接口地址:
http://api.tianditu.gov.cn/drive -
请求方式:
GET -
参数:
-
postStr: JSON 格式字符串,包含orig(起点经纬度)、dest(终点经纬度)、style(路线类型) -
tk: 天地图开发者密钥
-
返回结果是 XML 格式,需要自己解析。
3. 工具类封装
我把请求和解析过程都封装到了 TiandituRouteUtils,直接调用即可拿到 List<RoutePoint> 对象,包含经纬度、道路名称、导航提示等信息。
package com.zhy.common.utils.map;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
/**
* 天地图驾车路线规划工具类
* 可根据起点和终点经纬度,获取推荐路线点位
*
* @author GaXer
* @since 2025/09/24
*/
@Slf4j
public class TiandituRouteUtils {
/** 天地图驾车规划接口地址 */
private static final String ROUTE_URI = "http://api.tianditu.gov.cn/drive";
/**
* 路径规划
* @param origLon 起点经度
* @param origLat 起点纬度
* @param destLon 终点经度
* @param destLat 终点纬度
* @param driveKey 天地图Key
* @param style 路径类型(0:最快,1:最短,2:避开高速,3:步行)
* @return 推荐路线点位列表
*/
public static List<RoutePoint> getRecommendRoute(double origLon, double origLat,
double destLon, double destLat,
String driveKey, String style) {
List<RoutePoint> routeList = new ArrayList<>();
try {
// 构建请求参数
String postStr = String.format("{\"orig\":\"%f,%f\",\"dest\":\"%f,%f\",\"style\":\"%s\"}",
origLon, origLat, destLon, destLat, style);
try (HttpResponse response = HttpUtil.createGet(ROUTE_URI)
.form("postStr", postStr)
.form("type", "search")
.form("tk", driveKey)
.execute()) {
if (!response.isOk()) {
log.error("请求天地图失败,响应: {}", response.body());
return routeList;
}
String responseBody = response.body();
routeList = parseRouteList(responseBody);
}
} catch (Exception e) {
log.error("获取推荐路线失败", e);
}
return routeList;
}
/** 解析XML成路线点 */
private static List<RoutePoint> parseRouteList(String responseBody) throws Exception {
List<RoutePoint> routeList = new ArrayList<>();
try (ByteArrayInputStream inputStream =
new ByteArrayInputStream(responseBody.getBytes(StandardCharsets.UTF_8))) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inputStream);
document.getDocumentElement().normalize();
NodeList routesList = document.getElementsByTagName("routes");
if (routesList.getLength() > 0) {
Element routesElement = (Element) routesList.item(0);
NodeList items = routesElement.getElementsByTagName("item");
for (int idx = 0; idx < items.getLength(); idx++) {
Element item = (Element) items.item(idx);
RoutePoint routePoint = new RoutePoint();
routePoint.setId(IdUtil.getSnowflakeNextId());
routePoint.setGuide(getElementText(item, "strguide"));
routePoint.setStreetName(getElementText(item, "streetName"));
String[] latLon = getElementText(item, "turnlatlon").split(",");
routePoint.setLongitude(Double.parseDouble(latLon[0]));
routePoint.setLatitude(Double.parseDouble(latLon[1]));
routePoint.setSort(idx);
routeList.add(routePoint);
}
}
}
return routeList;
}
/** 获取某个XML子元素的文本内容 */
private static String getElementText(Element parent, String tagName) {
NodeList nodeList = parent.getElementsByTagName(tagName);
return (nodeList.getLength() > 0) ? nodeList.item(0).getTextContent().trim() : "";
}
/**
* 打印XML节点信息(调试用)
* @param element XML元素
*/
public static void parseElement(Element element) {
System.out.print("<" + element.getTagName());
NamedNodeMap attris = element.getAttributes();
for (int i = 0; i < attris.getLength(); i++) {
Attr attr = (Attr) attris.item(i);
System.out.print(" " + attr.getName() + "=\"" + attr.getValue() + "\"");
}
System.out.println(">");
NodeList nodeList = element.getChildNodes();
for (int temp = 0; temp < nodeList.getLength(); temp++) {
Node childNode = nodeList.item(temp);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
if (childNode.hasChildNodes()) {
parseElement((Element) childNode);
} else if (childNode.getNodeType() != Node.COMMENT_NODE) {
System.out.print(childNode.getTextContent());
}
}
}
System.out.println("</" + element.getTagName() + ">");
}
/** 路线点对象 */
@Data
public static class RoutePoint {
private Long id;
private double longitude;
private double latitude;
private int sort;
private String guide;
private String streetName;
}
}
使用示例
public class Demo {
public static void main(String[] args) {
String key = "你的天地图key";
List<TiandituRouteUtils.RoutePoint> route =
TiandituRouteUtils.getRecommendRoute(
113.665412, 34.757975, // 起点:郑州
114.305393, 30.593099, // 终点:武汉
key,
"0" // 最快路线
);
route.forEach(r -> System.out.printf("%d: %s (%f,%f)%n",
r.getSort(), r.getGuide(), r.getLongitude(), r.getLatitude()));
}
}
5. 应用场景
-
防汛指挥系统:村庄转移路线
-
农业水利平台:灌溉工程的巡查路径规划
-
智慧交通:车辆行驶推荐路线
6. 总结
通过这个工具类,我们可以:
-
免去手写 XML 解析的痛苦
-
快速拿到推荐路线的点位信息
-
在地图上直接绘制行进轨迹
如果你也在做类似的系统,可以直接拿去用。
更多推荐



所有评论(0)