From d4f8d30d1c6e4397dbfbdbb759cc66132913dd53 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期五, 13 三月 2026 11:34:35 +0800
Subject: [PATCH] 修改计费规则

---
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java |  252 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 238 insertions(+), 14 deletions(-)

diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java
index e09217c..0eb8c08 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java
@@ -7,32 +7,225 @@
 import com.xiaopeng.api.vo.operation.RouteVo;
 import com.xiaopeng.common.core.utils.HttpUtils;
 import com.xiaopeng.map.mangodb.service.XpGeoFencingPolygonService;
-import com.xiaopeng.map.utils.mangoUtils.MongoGeoFenceUtil;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * 高德地图的地理编码工具类
  */
+@Slf4j
 @Component
 @Lazy
 public class GDMapGeocodingUtil {
 
     private String key = "66ae577f63898dae3016d599fda57221";
 
-    @Autowired
-    private RestTemplate restTemplate;
-    
+
     @Autowired
     private XpGeoFencingPolygonService xpGeoFencingPolygonService;
+    // 自定义线程池配置
+    private static final int CORE_POOL_SIZE = 5;  // 核心线程数
+    private static final int MAX_POOL_SIZE = 10;  // 最大线程数
+    private static final long KEEP_ALIVE_TIME = 60L; // 线程空闲存活时间
+    private static final int QUEUE_CAPACITY = 100; // 阻塞队列容量
 
+    // 创建自定义线程池
+    private final ExecutorService customThreadPool = new ThreadPoolExecutor(
+            CORE_POOL_SIZE,
+            MAX_POOL_SIZE,
+            KEEP_ALIVE_TIME,
+            TimeUnit.SECONDS,
+            new LinkedBlockingQueue<>(QUEUE_CAPACITY),
+            new ThreadFactory() {
+                private final AtomicInteger threadNumber = new AtomicInteger(1);
+                @Override
+                public Thread newThread(Runnable r) {
+                    Thread t = new Thread(r, "route-check-thread-" + threadNumber.getAndIncrement());
+                    t.setDaemon(true); // 设置为守护线程,避免应用关闭时线程未停止
+                    return t;
+                }
+            },
+            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:调用线程执行
+    );
+
+//    public RouteVo getDistanceAndTime(LonLatDto start, LonLatDto end, String avoidRoads, String fenceId, Integer routePlanRule) {
+//        RouteVo routeVo = new RouteVo();
+//
+//        String url = "https://tsapi.amap.com/v1/route/price?key=" + key + "&extensions=all&start=" + start.getLongitude() + "," + start.getLatitude();
+//        HashMap<String, Object> params = new HashMap<>();
+//        params.put("extensions", "all");
+//        params.put("start", start.getLongitude() + "," + start.getLatitude());
+//        params.put("end", end.getLongitude() + "," + end.getLatitude());
+//        params.put("routeUserType", 2);
+//        if (avoidRoads != null && !avoidRoads.isEmpty()) {
+//            params.put("voidPolygons", avoidRoads);
+//        }
+//        if (routePlanRule != null) {
+//            params.put("strategy", routePlanRule);
+//        }
+//
+//        String post = HttpUtils.post(url, JSON.toJSONString(params));
+//        System.out.println("高德地图返回结果:" + post);
+//
+//        JSONObject jsonObject = JSON.parseObject(post);
+//        String data = jsonObject.getString("data");
+//        JSONObject jsonObject1 = JSON.parseObject(data);
+//        JSONArray path = jsonObject1.getJSONArray("paths");
+//
+//        if (path == null || path.isEmpty()) {
+//            return null;
+//        }
+//
+//        // 使用自定义线程池并行处理每个路径的围栏检查
+//        List<Future<PathCheckResult>> futures = new ArrayList<>();
+//        CountDownLatch latch = new CountDownLatch(path.size()); // 用于等待所有任务完成
+//
+//        // 提交每个路径的处理任务
+//        for (int j = 0; j < path.size(); j++) {
+//            final int index = j;
+//            JSONObject pathObject = path.getJSONObject(index);
+//
+//            Future<PathCheckResult> future = customThreadPool.submit(() -> {
+//                try {
+//                    PathCheckResult result = new PathCheckResult();
+//                    result.setIndex(index);
+//                    result.setPathObject(pathObject);
+//
+//                    String points = pathObject.getString("points");
+//                    String[] split = points.split(";");
+//
+//                    // 检查点位是否在围栏内
+//                    boolean inFence = checkPointsInFence(split, fenceId);
+//                    result.setInFence(inFence);
+//
+//                    return result;
+//                } finally {
+//                    latch.countDown(); // 任务完成,计数器减1
+//                }
+//            });
+//
+//            futures.add(future);
+//        }
+//
+//        try {
+//            // 等待所有任务完成,设置超时时间
+//            if (!latch.await(10, TimeUnit.SECONDS)) {
+//                System.out.println("路径检查任务超时");
+//                // 取消所有未完成的任务
+//                for (Future<PathCheckResult> future : futures) {
+//                    if (!future.isDone()) {
+//                        future.cancel(true);
+//                    }
+//                }
+//            }
+//        } catch (InterruptedException e) {
+//            Thread.currentThread().interrupt();
+//            System.out.println("路径检查任务被中断");
+//            return null;
+//        }
+//
+//        // 收集处理结果,找到第一个不在围栏内的路径
+//        PathCheckResult validPathResult = null;
+//
+//        for (Future<PathCheckResult> future : futures) {
+//            try {
+//                if (future.isDone() && !future.isCancelled()) {
+//                    PathCheckResult result = future.get();
+//                    if (!result.isInFence()) {
+//                        validPathResult = result;
+//                        break; // 找到有效的就停止
+//                    }
+//                }
+//            } catch (InterruptedException | ExecutionException e) {
+//                System.out.println("获取路径检查结果失败: " + e.getMessage());
+//                e.printStackTrace();
+//            }
+//        }
+//
+//        // 如果找到了有效路径,处理该路径数据
+//        if (validPathResult != null) {
+//            JSONObject validPath = validPathResult.getPathObject();
+//            String routeID = validPath.getString("routeID");
+//            String points = validPath.getString("points");
+//            String[] split = points.split(";");
+//
+//            Integer costTime = validPath.getInteger("costTime");
+//            Integer distance = validPath.getInteger("distance");
+//
+//            routeVo.setDistance(distance);
+//            routeVo.setDuration(costTime);
+//
+//            ArrayList<LonLatDto> lonLatDtos = new ArrayList<>(split.length);
+//            for (String s : split) {
+//                String[] split1 = s.split(",");
+//                LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split1[0]), Double.parseDouble(split1[1]));
+//                lonLatDtos.add(lonLatDto);
+//            }
+//            routeVo.setPolyline(lonLatDtos);
+//            routeVo.setRouteID(routeID);
+//
+//            return routeVo;
+//        }
+//
+//        return null;
+//    }
+    /**
+     * 路径检查结果内部类
+     */
+    private static class PathCheckResult {
+        private int index;
+        private JSONObject pathObject;
+        private boolean inFence; // true: 所有点都在围栏内, false: 有点不在围栏内
+
+        public int getIndex() {
+            return index;
+        }
+
+        public void setIndex(int index) {
+            this.index = index;
+        }
+
+        public JSONObject getPathObject() {
+            return pathObject;
+        }
+
+        public void setPathObject(JSONObject pathObject) {
+            this.pathObject = pathObject;
+        }
+
+        public boolean isInFence() {
+            return inFence;
+        }
+
+        public void setInFence(boolean inFence) {
+            this.inFence = inFence;
+        }
+    }
+    /**
+     * 检查路径点位是否在围栏内
+     */
+    private boolean checkPointsInFence(String[] points, String fenceId) {
+        // 取5分之一的点位进行检查
+        for (int i = 0; i < points.length; i++) {
+            if (i % 5 == 0) {
+                String[] split1 = points[i].split(",");
+                LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split1[0]), Double.parseDouble(split1[1]));
+                if (!xpGeoFencingPolygonService.isInFence(lonLatDto.getLongitude(), lonLatDto.getLatitude(), fenceId, "operating_area")) {
+                    return false; // 有点位不在围栏内
+                }
+            }
+        }
+        return true; // 所有检查的点都在围栏内
+    }
 
     /**
      * 根据起始点获取驾车距离 和 时间  以及避让区域
@@ -61,25 +254,24 @@
         if(routePlanRule!=null){
             params.put("strategy", routePlanRule);
         }
-
+        log.info("高德地图接口:{}", url);
+        log.info("高德地图参数:{}", params);
         String post = HttpUtils.post(url, JSON.toJSONString(params));
-        System.out.println("高德地图返回结果:"+ post);
-//        String forObject = restTemplate.getForObject(url, String.class, params);
+        log.info("高德地图返回结果:"+ post);
         JSONObject jsonObject = JSON.parseObject(post);
         String data = jsonObject.getString("data");
 
         JSONObject jsonObject1 = JSON.parseObject(data);
-        String routeID = jsonObject1.getString("routeID");
         JSONArray path = jsonObject1.getJSONArray("paths");
         for (Object o : path) {
             JSONObject jsonObject2 = (JSONObject) o;
-
+            String routeID = jsonObject2.getString("routeID");
             String points = jsonObject2.getString("points");
             String[] split = points.split(";");
             int temp=0;
             // 取5分之一的点位
             for (int i = 0; i < split.length; i++) {
-                if (i % 5 == 0) {
+                if (i % 10 == 0) {
                     String[] split1 = split[i].split(",");
                     LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split1[0]), Double.parseDouble(split1[1]));
                     if (!xpGeoFencingPolygonService.isInFence(lonLatDto.getLongitude(), lonLatDto.getLatitude(), fenceId, "operating_area")) {
@@ -123,9 +315,41 @@
         params.put("sdkVersion", "9.850.152.3.532");
         params.put("encoderVersion", "5.1");
         String post = HttpUtils.post(url, JSON.toJSONString(params));
-        System.out.println("高德地图返回结果:"+ post);
-        JSONObject jsonObject = JSON.parseObject(post);
-        return jsonObject.getString("data");
+        log.info("高德地图返回结果:"+ post);
+        return post;
+    }
+
+
+
+    /**
+     * 根据经纬度获取行政区域信息
+     * @param lon
+     * @param lan
+     * @return
+     * @throws Exception
+     */
+    public Map<String, String> geocode(String lon, String lan) {
+        String url = "https://restapi.amap.com/v3/geocode/regeo?key=" + key + "&location=" + lon + "," + lan;
+        String forObject = HttpUtils.sendGet(url);
+        JSONObject jsonObject = JSON.parseObject(forObject);
+        Map<String, String> map = new HashMap<>();
+        if(jsonObject.getString("status").equals("1")){
+            JSONObject regeocode = jsonObject.getJSONObject("regeocode");
+            JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
+            String address = regeocode.getString("formatted_address");
+            map.put("address", address);
+            String code = addressComponent.getString("adcode");
+            String province = addressComponent.getString("province");
+            String city = addressComponent.getString("city");
+            String district = addressComponent.getString("district");
+            map.put("province", province);
+            map.put("provinceCode", code.substring(0, 2) + "0000");
+            map.put("city", city);
+            map.put("cityCode", code.substring(0, 4) + "00");
+            map.put("district", district);
+            map.put("districtCode", code);
+        }
+        return map;
     }
 
 }

--
Gitblit v1.7.1