在现代应用程序开发中,位置服务变得越来越重要。无论是电子商务平台上的物流配送优化,还是社交网络中的好友定位功能,都离不开地理位置信息的处理。本文将详细介绍如何使用Java结合高德地图API来实现地址解析(即从给定的地址获取其对应的经纬度信息)以及两个地点之间的距离计算。
一、准备工作
首先,你需要注册一个高德开放平台账号,并创建一个应用以获取API Key。访问高德开放平台,按照指引完成这些步骤。确保你的项目已经集成了fastjson
库,用于JSON数据的解析。
二、引入依赖
如果你正在使用Maven构建工具,请在pom.xml
文件中添加以下依赖项:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version> <!-- 或者选择最新版本 -->
</dependency>
三、编码实现
地址解析:获取经纬度
我们将定义一个名为AddressLocationUtil
的工具类,其中包含方法getLonAndLatByAddress
,该方法接受一个地址字符串作为参数,并返回其对应的经纬度坐标。
public static String getLonAndLatByAddress(String address) {
String formattedUrl = String.format(GD_URL, address, KEY);
JSONObject responseJson = fetchJsonFromUrl(formattedUrl);
validateResponseStatus(responseJson);
JSONArray geocodesArray = responseJson.getJSONArray("geocodes");
if (geocodesArray == null || geocodesArray.isEmpty()) {
throw new RuntimeException("未找到与地址匹配的经纬度信息。");
}
return geocodesArray.getJSONObject(0).getString("location");
}
此方法通过向高德地图的地理编码API发送HTTP GET请求,然后解析返回的JSON响应,提取出所需的经纬度信息。
距离计算
同样地,我们还实现了getDistance
方法,用于计算两个指定经纬度点之间的直线距离(单位为千米)。
public static double getDistance(String lon1, String lat1, String lon2, String lat2) {
String urlString = String.format(DIS_URL, KEY, lat1 + "," + lon1, lat2 + "," + lon2); // 注意经纬度参数的顺序
JSONObject responseJson = fetchJsonFromUrl(urlString);
validateResponseStatus(responseJson);
JSONArray resultsArray = responseJson.getJSONArray("results");
if (resultsArray == null || resultsArray.isEmpty()) {
throw new RuntimeException("计算距离失败,结果为空");
}
return Double.parseDouble(resultsArray.getJSONObject(0).getString("distance")) / 1000;
}
这个方法通过调用高德地图的距离测量API来获取两点间的真实行驶距离或直线距离。
四、源代码
以下为分享的工具类:
public class AddressLocationUtil {
private static final String KEY = "自己的高德地图API Key";
public static final String GD_URL = "https://restapi.amap.com/v3/geocode/geo?address=%s&key=%s";
public static final String DIS_URL = "https://restapi.amap.com/v3/distance?key=%s&origins=%s,%s&destination=%s,%s";
private static final String SUCCESS_FLAG = "1";
/**
* 根据地址获取对应的经纬度信息
*/
public static String getLonAndLatByAddress(String address) {
String formattedUrl = String.format(GD_URL, address, KEY);
JSONObject responseJson = fetchJsonFromUrl(formattedUrl);
validateResponseStatus(responseJson);
JSONArray geocodesArray = responseJson.getJSONArray("geocodes");
if (geocodesArray == null || geocodesArray.isEmpty()) {
throw new RuntimeException("未找到与地址匹配的经纬度信息。");
}
return geocodesArray.getJSONObject(0).getString("location");
}
/**
* 计算两个经纬度点之间的直线距离(单位:千米)
* @param lat1 点1纬度
* @param lon1 点1经度
* @param lat2 点2纬度
* @param lon2 点2经度
* @return 距离(千米)
*/
public static double getDistance(String lon1, String lat1, String lon2, String lat2) {
String urlString = String.format(DIS_URL, KEY, lat1 + "," + lon1, lat2 + "," + lon2); // 注意经纬度参数的顺序
JSONObject responseJson = fetchJsonFromUrl(urlString);
validateResponseStatus(responseJson);
JSONArray resultsArray = responseJson.getJSONArray("results");
if (resultsArray == null || resultsArray.isEmpty()) {
throw new RuntimeException("计算距离失败,结果为空");
}
return Double.parseDouble(resultsArray.getJSONObject(0).getString("distance")) / 1000;
}
/**
* 发送请求并返回JSON响应
*/
private static JSONObject fetchJsonFromUrl(String serverUrl) {
try {
URL url = new URL(serverUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
StringBuilder jsonResponse = new StringBuilder();
try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
jsonResponse.append(inputLine);
}
}
return JSONObject.parseObject(jsonResponse.toString());
} catch (Exception e) {
throw new RuntimeException("HTTP请求失败", e);
}
}
/**
* 验证API响应状态是否成功
*/
private static void validateResponseStatus(JSONObject responseJson) {
if (!SUCCESS_FLAG.equals(responseJson.getString("status"))) {
throw new RuntimeException("请求失败,错误码:" + responseJson.getString("infocode"));
}
}
}
获取位置详细信息
AddressLocationUtil.getLonAndLatByAddress("四川省成都市人民政府")
获取两点间距离
AddressLocationUtil.getDistance("104.2564456","29.56789475","104.15888966","29.5879534")
// 注意不能使用境外地址
五、总结
通过本文的介绍,我们了解了如何利用Java语言与高德地图API交互,执行地址解析和距离计算任务。这些功能在许多实际应用场景中都非常有用,例如在线购物平台上的物流规划、社交软件中的位置共享等。希望这篇文章能为你提供有价值的参考,并激发你在自己的项目中探索更多可能性。