| | |
| | | import com.xiaopeng.api.dto.pushMessage.PushOrderRouteDTO; |
| | | import com.xiaopeng.api.dto.pushMessage.SendMessageDTO; |
| | | import com.xiaopeng.api.feignClient.order.XpOrderClient; |
| | | import com.xiaopeng.api.feignClient.order.XpTestOrderClient; |
| | | import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; |
| | | import com.xiaopeng.api.model.order.XpOrder; |
| | | import com.xiaopeng.api.model.order.XpTestOrder; |
| | | import com.xiaopeng.api.vo.operation.RouteVo; |
| | | import com.xiaopeng.common.core.constant.CacheConstants; |
| | | import com.xiaopeng.common.core.constant.Constants; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.enums.PushMessageTypeEnum; |
| | | import com.xiaopeng.common.redis.service.RedisService; |
| | | import com.xiaopeng.pushMessage.utils.MapMatchingUtil; |
| | | import com.xiaopeng.pushMessage.utils.TrackPoint; |
| | | import com.xiaopeng.pushMessage.utils.TrajectoryDensifier; |
| | | import io.swagger.annotations.Api; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.powermock.core.ListMap; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.time.Instant; |
| | | import java.util.*; |
| | | import java.util.concurrent.LinkedBlockingQueue; |
| | | import java.util.concurrent.ThreadPoolExecutor; |
| | |
| | | Integer routeType = dto.getRouteType(); |
| | | //正常订单 |
| | | if(routeType == 1){ |
| | | //非导航偏离才需要限频 |
| | | if(PushMessageTypeEnum.ORDER_ROUTE.getDesc().equals(dto.getMessageType())){ |
| | | Long pushTime = redisService.getCacheObject("PUSH_TIME:" + dto.getOrderId()); |
| | | if(null != pushTime && System.currentTimeMillis() - pushTime < 1500){ |
| | | return R.ok(); |
| | | } |
| | | redisService.setCacheObject("PUSH_TIME:" + dto.getOrderId(), System.currentTimeMillis()); |
| | | } |
| | | XpOrder xpOrder = xpOrderClient.queryOrderById(dto.getOrderId()).getData(); |
| | | if(xpOrder.getStatus() <= 1 || xpOrder.getStatus() >= 8){ |
| | | return R.ok(); |
| | | } |
| | | // 获取路线规划 |
| | | String key = ""; |
| | | //接驾情况,获取车辆位置到起点的导航 |
| | | if(xpOrder.getStatus() == 2 || xpOrder.getStatus() == 3){ |
| | | if(xpOrder.getStatus() >= 2 && xpOrder.getStatus() <= 4){ |
| | | key = "ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId(); |
| | | }else{ |
| | | key = "ORDER_NAVIGATION_END_DATA:" + xpOrder.getAppUserId(); |
| | | } |
| | | Object cacheObject = redisService.getCacheObject(key); |
| | | RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class); |
| | | log.info("缓存获取的轨迹 {}", JSON.toJSONString(routeVo)); |
| | | log.info("缓存获取的轨迹 {} {}", key, JSON.toJSONString(routeVo)); |
| | | if(Objects.nonNull(routeVo)){ |
| | | //开始对轨迹进行点位补全,然后更新缓存中的轨迹数据 |
| | | if(xpOrder.getStatus() == 2 || xpOrder.getStatus() == 5){ |
| | | if(null == routeVo.getDensify() || routeVo.getDensify() == 0){ |
| | | log.info("开始执行点位补全 {}", key); |
| | | List<LonLatDto> polyline = routeVo.getPolyline(); |
| | | List<LonLatDto> new_polyline = new ArrayList<>(); |
| | | for (int i = 0; i < polyline.size(); i++) { |
| | | if(i == polyline.size() - 1){ |
| | | new_polyline.add(polyline.get(i)); |
| | | break; |
| | | } |
| | | LonLatDto lonLatDto = polyline.get(i); |
| | | LonLatDto lonLatDto1 = polyline.get(i + 1); |
| | | //对两个点位进行坐标补全 |
| | | List<TrackPoint> track = new ArrayList<>(); |
| | | // 模拟数据:两个点相差 20 秒 |
| | | track.add(new TrackPoint(lonLatDto.getLatitude(), lonLatDto.getLongitude(), null)); |
| | | track.add(new TrackPoint(lonLatDto1.getLatitude(), lonLatDto1.getLongitude(), null)); |
| | | //10米补全一个点位 |
| | | List<TrackPoint> densified = TrajectoryDensifier.densifyByTime(track, 10); |
| | | for (TrackPoint trackPoint : densified) { |
| | | new_polyline.add(new LonLatDto(trackPoint.getLongitude(), trackPoint.getLatitude())); |
| | | } |
| | | } |
| | | routeVo.setPolyline(new_polyline); |
| | | List<LonLatDto> densify = TrajectoryDensifier.densify(polyline, 15); |
| | | routeVo.setPolyline(densify); |
| | | routeVo.setDensify(1); |
| | | log.info("点位补全结束 {} {}", key, JSON.toJSONString(routeVo)); |
| | | redisService.setCacheObject(key, JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS); |
| | | } |
| | | Integer distance = dto.getDistance(); |
| | | Integer duration = dto.getDuration(); |
| | | |
| | | Integer distance = dto.getDistance().intValue(); |
| | | Integer duration = dto.getDuration().intValue(); |
| | | // 计算实时点位到线段的最优截取 |
| | | Map<String, List<LonLatDto>> remainingNavigation = MapMatchingUtil.getRemainingNavigation(routeVo.getPolyline(), dto.getLongitude(), dto.getLatitude()); |
| | | log.info("remainingNavigation {}", JSON.toJSONString(remainingNavigation)); |
| | | //当订单状态为5的时候(乘客已上车)需要推送导航的距离和剩余时间 |
| | | //因为这个状态,车端推的依然是接驾的剩余里程和时间,就会导致数据和小程序的页面跳转匹配不上 |
| | | //小程序是只要乘客上车后就跳转到行程开始页面 |
| | |
| | | } |
| | | List<LonLatDto> lonLatDtos = remainingNavigation.get("unserved"); |
| | | List<LonLatDto> lonLatDtos1 = remainingNavigation.get("served"); |
| | | |
| | | routeVo.setPolyline(lonLatDtos); |
| | | routeVo.setServed(lonLatDtos1); |
| | | log.info("线路截取后存储的轨迹 {}", JSON.toJSONString(routeVo)); |
| | |
| | | content.put("routeType",routeType); |
| | | content.put("direction",dto.getDirection()); |
| | | content.put("route",JSONObject.toJSONString(route)); |
| | | content.put("endLongitude", dto.getEndLongitude()); |
| | | content.put("endLatitude", dto.getEndLatitude()); |
| | | |
| | | // 封装轨迹信息 |
| | | Map<String, Object> params = new HashMap<>(); |
| | | params.put("type", PushMessageTypeEnum.ORDER_ROUTE.getDesc()); |
| | | params.put("type", dto.getMessageType()); |
| | | params.put("content", JSONObject.toJSONString(content)); |
| | | params.put("timestamp", new Date().getTime()+""); |
| | | |