package com.xiaopeng.map.controller; import com.xiaopeng.api.dto.map.OrderRouteAndFareDto; import com.xiaopeng.api.dto.map.RouteAndFareDto; import com.xiaopeng.api.dto.operation.LonLatDto; import com.xiaopeng.api.feignClient.order.XpOrderClient; import com.xiaopeng.api.model.order.XpOrder; import com.xiaopeng.api.vo.map.PointByIpVo; import com.xiaopeng.api.vo.map.XpDistanceAndDurationVo; import com.xiaopeng.api.vo.operation.RouteVo; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.redis.service.RedisService; import com.xiaopeng.map.mangodb.model.GeoPoint; import com.xiaopeng.map.mangodb.service.XpGeoFencingPolygonService; import com.xiaopeng.map.utils.AmapWalkingRouteUtil; import com.xiaopeng.map.utils.GDMapGeocodingUtil; import com.xiaopeng.map.utils.mangoUtils.MongoGeoFenceUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.bson.Document; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @Slf4j @RestController @RequestMapping("") @Api(tags = "地图调用服务") public class XpMapController { private final GDMapGeocodingUtil gdMapGeocodingUtil; private final XpGeoFencingPolygonService xpGeoFencingPolygonService; private final RedisService redisService; private final XpOrderClient xpOrderClient; private final MongoTemplate mongoTemplate; public XpMapController(GDMapGeocodingUtil gdMapGeocodingUtil, XpGeoFencingPolygonService xpGeoFencingPolygonService, RedisService redisService, XpOrderClient xpOrderClient, MongoTemplate mongoTemplate) { this.gdMapGeocodingUtil = gdMapGeocodingUtil; this.xpGeoFencingPolygonService = xpGeoFencingPolygonService; this.redisService = redisService; this.xpOrderClient = xpOrderClient; this.mongoTemplate = mongoTemplate; } @PostMapping("/base/v1/map/getDistanceAndDuration") public R getDistanceAndDuration(@RequestBody RouteAndFareDto dto){ // 获取电子围栏的禁行区域点位 GeoPoint startPoint = new GeoPoint(dto.getOrigin().getLongitude(),dto.getOrigin().getLatitude()); List operatingArea = xpGeoFencingPolygonService.findFencesContainingPoint(startPoint, "operating_area", "points"); String fenceId = operatingArea.get(0); List pointsInFence = xpGeoFencingPolygonService.findPointsByParentId(fenceId, "fenceId", "prohibited_area"); // 避让区域 ArrayList 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>> coordinates = (List>>) geoJsonDoc.get("coordinates"); if (coordinates != null && !coordinates.isEmpty()) { // 获取第一个多边形环(通常只有一个) List> polygonPoints = coordinates.get(0); // 转换为经纬度字符串 ArrayList pointStr = new ArrayList<>(); for (List point : polygonPoints) { if (point.size() >= 2) { pointStr.add(point.get(0) + "," + point.get(1)); } } if (!pointStr.isEmpty()) { pointStrParam.add(String.join(";", pointStr)); } } } } RouteVo routeVo = gdMapGeocodingUtil.getDistanceAndTime(dto.getOrigin(), dto.getDestination(), String.join("|", pointStrParam), fenceId,dto.getRoutePlanRule()); if(routeVo==null){ return R.fail("没有找到路线"); } return R.ok(routeVo); }catch (Exception e){ e.printStackTrace(); } return R.fail("没有找到路线"); } /** * 获取订单距离和时长 * @param dto * @return */ @PostMapping("/base/v1/map/getOrderDistanceAndDuration") public R getOrderDistanceAndDuration(@Validated @RequestBody OrderRouteAndFareDto dto){ // 获取电子围栏的禁行区域点位 GeoPoint startPoint = new GeoPoint(dto.getOrigin().getLongitude(),dto.getOrigin().getLatitude()); List operatingArea = xpGeoFencingPolygonService.findFencesContainingPoint(startPoint, "operating_area", "points"); // 避让区域 ArrayList pointStrParam = new ArrayList<>(); String fenceId = null; if(!operatingArea.isEmpty()){ fenceId = operatingArea.get(0); List pointsInFence = xpGeoFencingPolygonService.findPointsByParentId(fenceId, "parentId", "prohibited_area"); for (Document document : pointsInFence) { List points = document.getList("points", GeoPoint.class); // 一个区域的点位 ArrayList pointStr = new ArrayList<>(); for (GeoPoint point : points) { pointStr.add( point.getLongitude()+","+point.getLatitude()); } if(!pointStr.isEmpty()){ pointStrParam.add(String.join(";", pointStr)); } } } RouteVo routeVo = gdMapGeocodingUtil.getDistanceAndTime(dto.getOrigin(), dto.getDestination(), String.join("|", pointStrParam), fenceId,dto.getRoutePlanRule()); if(routeVo==null){ return R.fail("没有找到路线"); } // 存储redis redisService.setCacheObject(CacheConstants.ORDER_ROUTE + "_" + dto.getOrderId() + "_" +dto.getRouteType(), routeVo); // 存储路线偏离缓存,后续进行轨迹截取 // redisService.setCacheObject(CacheConstants.ORDER_ROUTE_CAPTURE + "_" + dto.getOrderId() + "_" +dto.getRouteType(), routeVo); // 存储路线偏离缓存,后续进行轨迹截取 redisService.setCacheObject(CacheConstants.ORDER_ROUTE_CAPTURE + "_" + dto.getOrderId() + "_" +dto.getRouteType(), routeVo); return R.ok(routeVo); } /** * 根据导航ID获取车端需要的导航数据 * @param routedID * @return */ @PostMapping("/base/v1/map/queryRouted") public R getOrderDistanceAndDuration(@RequestParam("routedID") String routedID){ return R.ok(gdMapGeocodingUtil.routed(routedID)); } /** * 根据ip获取点位 */ @ApiOperation(value = "根据ip获取点位", tags = {"小程序-站点导航"}) @GetMapping("/base/v1/mini-program/point/getPointByIp") public R getPointByIp(HttpServletRequest request) throws IOException { String ip = request.getRemoteAddr(); PointByIpVo pointByIpVo = AmapWalkingRouteUtil.ipLocation(ip); return R.ok(pointByIpVo); } }