xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/map/XpMapClientFallbackFactory.java
@@ -12,6 +12,8 @@ import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.stereotype.Component; import java.util.List; @Slf4j @Component public class XpMapClientFallbackFactory implements FallbackFactory<XpMapClient> { @@ -25,6 +27,12 @@ } @Override public R<List<RouteVo>> getDistanceAndDurationList(RouteAndFareDto dto) { log.error("获取距离和时长失败:{}", cause.getMessage()); return R.fail("获取距离和时长失败"); } @Override public R<RouteVo> getOrderDistanceAndDuration(OrderRouteAndFareDto dto) { log.error("获取订单距离和时长失败:{}", cause.getMessage()); return R.fail("获取订单距离和时长失败,"+cause.getMessage()); xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/map/XpMapClient.java
@@ -15,6 +15,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; @FeignClient(contextId = "XpMapClient", value = ServiceNameConstantsEnum.XP_MAP_SERVICE, fallbackFactory = XpMapClientFallbackFactory.class) public interface XpMapClient { /** @@ -25,6 +27,15 @@ @PostMapping("/base/v1/map/getDistanceAndDuration") R<RouteVo> getDistanceAndDuration(@RequestBody RouteAndFareDto dto); /** * 获取距离和时长 * @param dto * @return */ @PostMapping("/base/v1/map/getDistanceAndDurationList") R<List<RouteVo>> getDistanceAndDurationList(@RequestBody RouteAndFareDto dto); /** * 获取距离和时长 * @param dto xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -652,7 +652,7 @@ dto.setLatitude(latitude); dto.setDuration(10.0); dto.setDistance(2.0); dto.setSpeed(2.0); dto.setSpeed(2.0f); dto.setDirection(60); dto.setMessageType(PushMessageTypeEnum.ORDER_ROUTE.getDesc()); xpPushMessageClient.pushOrderRoute(dto); @@ -835,7 +835,7 @@ dto.setLatitude(latitude); dto.setDuration(20.0); dto.setDistance(10.0); dto.setSpeed(10.0); dto.setSpeed(10.0f); dto.setDirection(60); dto.setMessageType(PushMessageTypeEnum.ORDER_ROUTE.getDesc()); R<String> stringR = xpPushMessageClient.pushOrderRoute(dto); xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -1150,21 +1150,23 @@ copy.setOrigin(routeAndFareDto.getOrigin()); copy.setDestination(routeAndFareDto.getDestination()); copy.setRoutePlanRule(kind.getAmapStrategy()); R<RouteVo> r = xpMapClient.getDistanceAndDuration(copy); if (r.getCode() != 200 || r.getData() == null || r.getData().getRouteID() == null) { R<List<RouteVo>> r = xpMapClient.getDistanceAndDurationList(copy); if (r.getCode() != 200 || r.getData() == null || r.getData().isEmpty()) { continue; } if(CollUtil.isNotEmpty(routePoints)){ bb: for (RouteVo datum : r.getData()) { for (List<LonLatDto> routePoint : routePoints) { if(CollUtil.isEqualList(routePoint, r.getData().getPolyline())){ continue aa; if(CollUtil.isEqualList(routePoint, datum.getPolyline())){ continue bb; } } routePoints.add(datum.getPolyline()); String fid = datum.getRouteID(); routeById.putIfAbsent(fid, datum); strategiesById.computeIfAbsent(fid, k -> new LinkedHashSet<>()).add(kind); continue aa; } routePoints.add(r.getData().getPolyline()); String fid = r.getData().getRouteID(); routeById.putIfAbsent(fid, r.getData()); strategiesById.computeIfAbsent(fid, k -> new LinkedHashSet<>()).add(kind); } if (routeById.isEmpty()) { xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
@@ -73,6 +73,71 @@ } @PostMapping("/base/v1/map/getDistanceAndDurationList") public R<List<RouteVo>> getDistanceAndDurationList(@RequestBody RouteAndFareDto dto){ // 获取电子围栏的禁行区域点位 GeoPoint startPoint = new GeoPoint(dto.getOrigin().getLongitude(),dto.getOrigin().getLatitude()); List<String> operatingArea = xpGeoFencingPolygonService.findFencesContainingPoint(startPoint, "operating_area", "points"); String fenceId = operatingArea.get(0); List<Document> pointsInFence = xpGeoFencingPolygonService.findPointsByParentId(fenceId, "fenceId", "prohibited_area"); // 避让区域 ArrayList<JSONObject> pointStrParam = new ArrayList<>(); try { for (Document document : pointsInFence) { // 获取points字段(它是GeoJSON对象) Document geoJsonDoc = document.get("points", Document.class); if (geoJsonDoc != null && "Polygon".equals(geoJsonDoc.getString("type"))) { // 获取coordinates数组 List<List<List<Double>>> coordinates = (List<List<List<Double>>>) geoJsonDoc.get("coordinates"); if (coordinates != null && !coordinates.isEmpty()) { // 获取第一个多边形环(通常只有一个) List<List<Double>> polygonPoints = coordinates.get(0); List<String> coordinatesList = new ArrayList<>(); // 转换为经纬度字符串 for (List<Double> point : polygonPoints) { if (point.size() >= 2) { coordinatesList.add(point.get(0) + "," + point.get(1)); } } JSONObject jsonObject = new JSONObject(); jsonObject.put("coordinates", coordinatesList); pointStrParam.add(jsonObject); } } } List<HistoryPointDto> history = new ArrayList<>(); if(null != dto.getVehicleId()){ // history = redisService.getCacheList("VEHICLE_HISTORY_POINT_LIST:" + dto.getVehicleId()); // if(history.size() > 10){ // history = history.subList(history.size() - 10, history.size()); // } // history.forEach(s->{ // s.setDirection(new BigDecimal(s.getDirection()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()); // }); // redisService.setCacheList("VEHICLE_HISTORY_POINT_LIST:" + dto.getVehicleId(), history); } List<RouteVo> routeVo = gdMapGeocodingUtil.getDistanceAndTimeList(dto.getOrigin(), dto.getDestination(), pointStrParam, fenceId,dto.getRoutePlanRule(), history); if(routeVo==null || routeVo.isEmpty()){ return R.fail("没有找到路线"); } return R.ok(routeVo); }catch (Exception e){ e.printStackTrace(); } return R.fail("没有找到路线"); } @PostMapping("/base/v1/map/getDistanceAndDuration") public R<RouteVo> getDistanceAndDuration(@RequestBody RouteAndFareDto dto){ // 获取电子围栏的禁行区域点位 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java
@@ -154,6 +154,84 @@ } /** * 根据起始点获取驾车距离 和 时间 以及避让区域 * * @param start 起点 * @param end 终点 * @param avoidRoads 避让点 * @param fenceId mango id * @param routePlanRule 线路规划规则 * @return * @throws Exception */ public List<RouteVo> getDistanceAndTimeList(LonLatDto start, LonLatDto end,ArrayList<JSONObject> avoidRoads,String fenceId,Integer routePlanRule, List<HistoryPointDto> history) { 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("avoidPolygons", avoidRoads); } if (routePlanRule != null) { params.put("strategy", routePlanRule); } if(null != history && !history.isEmpty()){ params.put("history", history); } log.info("高德地图接口:{}", url); log.info("高德地图参数:{}", JSON.toJSONString(params)); String post = HttpUtils.post(url, JSON.toJSONString(params)); log.info("高德地图返回结果:" + post); JSONObject jsonObject = JSON.parseObject(post); String data = jsonObject.getString("data"); JSONObject jsonObject1 = JSON.parseObject(data); JSONArray path = jsonObject1.getJSONArray("paths"); log.info("开始判断导航路径是否在运营区域范围内 {}", fenceId); List<RouteVo> list = new ArrayList<>(); for (Object o : path) { RouteVo routeVo = new RouteVo(); JSONObject jsonObject2 = (JSONObject) o; String routeID = jsonObject2.getString("routeID"); String points = jsonObject2.getString("points"); String[] split = points.split(";"); List<LonLatDto> pointsArray = new ArrayList<>(); for (int i = 0; i < split.length; i++) { if((i % 2) == 0){ String[] split1 = split[i].split(","); LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split1[0]), Double.parseDouble(split1[1])); pointsArray.add(lonLatDto); } } ForkJoinPool pool = new ForkJoinPool(); // 创建ForkJoinPool对象(默认使用处理器的核心数作为线程池大小) ArrayPointsTask arrayPointsTask = new ArrayPointsTask(pointsArray, fenceId); // 创建求和任务对象并传入数组作为参数(这里也可以传入数组的一部分作为参数来实现更细粒度的拆分) Long temp = pool.invoke(arrayPointsTask); // 提交任务并等待处理完成(也可以使用submit方法提交任务并获取一个Future对象来异步获取结果) pool.shutdown(); // 关闭ForkJoinPool(释放资源) if (temp == 0) { Integer costTime = jsonObject2.getInteger("costTime"); Integer distance = jsonObject2.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); log.info("导航 {} 在 {} 运营区域内", routeVo.getRouteID(), fenceId); list.add(routeVo); } } return list; } public static void main(String[] args) { String url = "https://tsapi.amap.com/v1/route/price?key=" + "66ae577f63898dae3016d599fda57221" + "&extensions=all&start=" + "113.384932" + "," + "23.155455"; HashMap<String, Object> params = new HashMap<>(); xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPointServiceImpl.java
@@ -189,6 +189,7 @@ nearestNextVo.setTime(xpPoint.getParkingTimeLimit()); nearestNextVo.setElectronicAreaId(xpPoint.getElectronicAreaId()); nearestNextVo.setStationId(xpPoint.getStationId()==null?null:xpPoint.getStationId().toString()); nearestNextVo.setIsCollect(2); // 判断是否收藏 if(pointIdsByUserId.getData()!=null && !pointIdsByUserId.getData().isEmpty()){ @@ -200,8 +201,17 @@ nearestNextVos.add(nearestNextVo); } } List<NearestNextVo> objects = new ArrayList<NearestNextVo>(); if (!nearestNextVos.isEmpty()) { nearestNextVos = nearestNextVos.stream().sorted(Comparator.comparing(NearestNextVo::getDistance)).collect(Collectors.toList()); //收藏的数据 List<NearestNextVo> collect = nearestNextVos.stream().filter(s -> s.getIsCollect() == 1) .sorted(Comparator.comparing(NearestNextVo::getDistance).reversed()).collect(Collectors.toList()); objects.addAll(collect); //非收藏的数据 List<NearestNextVo> collect1 = nearestNextVos.stream().filter(s -> s.getIsCollect() == 2) .sorted(Comparator.comparing(NearestNextVo::getDistance).reversed()).collect(Collectors.toList()); objects.addAll(collect1); } nearestVo.setPoints(nearestNextVos); nearestVo.setTotal(nearestNextVos.size()); xp-robotaxi-operation-boot/src/main/resources/bootstrap.yml
@@ -28,6 +28,7 @@ namespace: 88de3938-82f9-4cab-97cf-6173202703e0 username: nacos password: nacos ip: 192.168.110.85 config: # 配置中心地址 server-addr: 192.168.110.80:8848 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -1672,10 +1672,19 @@ } ); } data = data.stream().sorted(Comparator.comparingInt(XpHistoryStartPointsVo::getNum).reversed()).collect(Collectors.toList()); return data; List<XpHistoryStartPointsVo> objects = new ArrayList<XpHistoryStartPointsVo>(); if(!data.isEmpty()){ //收藏的数据 List<XpHistoryStartPointsVo> collect = data.stream().filter(s -> s.getIsCollect() == 1).collect(Collectors.toList()); collect.sort(Comparator.comparingInt(XpHistoryStartPointsVo::getNum).reversed()); objects.addAll(collect); //非收藏的数据 List<XpHistoryStartPointsVo> collect1 = data.stream().filter(s -> s.getIsCollect() == 2).collect(Collectors.toList()); collect1.sort(Comparator.comparingInt(XpHistoryStartPointsVo::getNum).reversed()); objects.addAll(collect1); } return objects; } @Override @@ -1703,9 +1712,18 @@ } ); } data = data.stream().sorted(Comparator.comparingInt(XpHistoryEndPointsVo::getNum).reversed()).collect(Collectors.toList()); return data; List<XpHistoryEndPointsVo> objects = new ArrayList<XpHistoryEndPointsVo>(); if(!data.isEmpty()){ //收藏的数据 List<XpHistoryEndPointsVo> collect = data.stream().filter(s -> s.getIsCollect() == 1).collect(Collectors.toList()); collect.sort(Comparator.comparingInt(XpHistoryEndPointsVo::getNum).reversed()); objects.addAll(collect); //非收藏的数据 List<XpHistoryEndPointsVo> collect1 = data.stream().filter(s -> s.getIsCollect() == 2).collect(Collectors.toList()); collect1.sort(Comparator.comparingInt(XpHistoryEndPointsVo::getNum).reversed()); objects.addAll(collect1); } return objects; }