| | |
| | | package com.doumee.core.utils.Tencent;/** |
| | | * Created by IntelliJ IDEA. |
| | | package com.doumee.core.utils.Tencent; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.doumee.core.utils.Http; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.URLEncoder; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 腾讯地图工具类 |
| | | * |
| | | * @Author : Rk |
| | | * @create 2026/4/14 15:58 |
| | | */public class MapUtil { |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class MapUtil { |
| | | |
| | | private static String tencentKey; |
| | | |
| | | /** 距离矩阵API */ |
| | | public static final String MATRIX_URL = "https://apis.map.qq.com/ws/distance/v1/matrix"; |
| | | |
| | | /** 支持的模式 */ |
| | | private static final List<String> SUPPORTED_MODES = Arrays.asList("driving", "bicycling"); |
| | | |
| | | @Value("${tencent_key}") |
| | | public void setTencentKey(String tencentKey) { |
| | | MapUtil.tencentKey = tencentKey; |
| | | } |
| | | |
| | | /** |
| | | * 批量距离矩阵计算 |
| | | * |
| | | * @param mode 模式:driving(驾车)、bicycling(自行车) |
| | | * @param fromPoints 起点列表,格式:lat,lng(最多10个) |
| | | * @param toPoints 终点列表,格式:lat,lng(最多20个) |
| | | * @return result.rows 矩阵数据,每个元素包含 distance(米) 和 duration(秒) |
| | | */ |
| | | public static JSONObject distanceMatrix(String mode, List<String> fromPoints, List<String> toPoints) { |
| | | if (!SUPPORTED_MODES.contains(mode)) { |
| | | throw new IllegalArgumentException("不支持的模式: " + mode + ",仅支持: " + SUPPORTED_MODES); |
| | | } |
| | | if (fromPoints == null || fromPoints.isEmpty() || toPoints == null || toPoints.isEmpty()) { |
| | | throw new IllegalArgumentException("起点和终点列表不能为空"); |
| | | } |
| | | |
| | | String from = String.join(";", fromPoints); |
| | | String to = String.join(";", toPoints); |
| | | |
| | | try { |
| | | String url = MATRIX_URL |
| | | + "?key=" + tencentKey |
| | | + "&mode=" + mode |
| | | + "&from=" + URLEncoder.encode(from, "UTF-8") |
| | | + "&to=" + URLEncoder.encode(to, "UTF-8"); |
| | | |
| | | log.info("腾讯地图矩阵API请求: mode={}, from={}, to={}", mode, from, to); |
| | | |
| | | JSONObject json = new Http().build(url) |
| | | .setConnectTimeout(5000) |
| | | .setReadTimeout(10000) |
| | | .get() |
| | | .toJSONObject(); |
| | | |
| | | log.info("腾讯地图矩阵API响应: {}", json); |
| | | |
| | | if (json.getIntValue("status") != 0) { |
| | | throw new RuntimeException("腾讯地图矩阵API调用失败: " + json.getString("message")); |
| | | } |
| | | |
| | | return json.getJSONObject("result"); |
| | | } catch (IOException e) { |
| | | log.error("腾讯地图矩阵API调用异常", e); |
| | | throw new RuntimeException("腾讯地图矩阵API调用异常", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 单对距离计算(便捷方法) |
| | | * |
| | | * @param mode 模式:driving(驾车)、bicycling(自行车) |
| | | * @param from 起点格式:lat,lng |
| | | * @param to 终点格式:lat,lng |
| | | * @return 第一个元素的 distance(米) 和 duration(秒) |
| | | */ |
| | | public static JSONObject distanceSingle(String mode, String from, String to) { |
| | | JSONObject result = distanceMatrix(mode, |
| | | Arrays.asList(from), |
| | | Arrays.asList(to)); |
| | | JSONArray rows = result.getJSONArray("rows"); |
| | | if (rows != null && !rows.isEmpty()) { |
| | | JSONArray elements = rows.getJSONObject(0).getJSONArray("elements"); |
| | | if (elements != null && !elements.isEmpty()) { |
| | | return elements.getJSONObject(0); |
| | | } |
| | | } |
| | | return new JSONObject(); |
| | | } |
| | | |
| | | /** |
| | | * 多起点到单终点(便捷方法) |
| | | * 返回每个起点到终点的距离和耗时,顺序与fromPoints对应 |
| | | * |
| | | * @param mode 模式 |
| | | * @param fromPoints 起点列表 |
| | | * @param to 单个终点 |
| | | * @return 距离耗时列表,顺序与fromPoints对应 |
| | | */ |
| | | public static List<JSONObject> distanceToOne(String mode, List<String> fromPoints, String to) { |
| | | JSONObject result = distanceMatrix(mode, fromPoints, Arrays.asList(to)); |
| | | JSONArray rows = result.getJSONArray("rows"); |
| | | return rows == null ? Arrays.asList() : rows.stream() |
| | | .map(row -> ((JSONObject) row).getJSONArray("elements").getJSONObject(0)) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | } |