wlzboy
2025-10-26 2c86a8bd60deed0dd0e044bad6fb83f75d19a332
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/VehicleGpsController.java
@@ -3,9 +3,14 @@
import java.util.*;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import com.ruoyi.common.config.TencentMapConfig;
import com.ruoyi.common.config.BaiduMapConfig;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -24,6 +29,7 @@
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.http.HttpUtils;
/**
 * 车辆GPS坐标Controller
@@ -51,6 +57,12 @@
    @Autowired
    private ICmsGpsCollectService cmsGpsCollectService;
    @Autowired
    private TencentMapConfig tencentMapConfig;
    @Autowired
    private BaiduMapConfig baiduMapConfig;
   /**
     * 查询车辆GPS坐标列表
@@ -139,6 +151,8 @@
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String beginTime= sdf.format(dispatchOrd.getDispatchOrdStartDate());
            String endTime=  sdf.format(new Date());
            logger.info("查询车辆轨迹:车辆号:{}, 开始时间:{}, 结束时间:{}", vehicleNo, beginTime, endTime);
            return this.getAnonymousTracks(vehicleNo,beginTime,endTime);
//
//        vehicleGps.setVehicleNo(tbVehicleOrder.getVehicle());
@@ -231,13 +245,14 @@
            }
            // 处理开始时间
                beginTime = beginTime.replace("T", " ").replace(" ","%20");
                beginTime = beginTime.replace("T", " ");
                if (beginTime.split(":").length == 2) { // 只有小时和分钟
                    beginTime += ":00";
                }
                
                // 处理结束时间
                endTime = endTime.replace("T", " ").replace(" ","%20");
//                endTime = endTime.replace("T", " ").replace(" ","%20");
            endTime = endTime.replace("T", " ");
                if (endTime.split(":").length == 2) { // 只有小时和分钟
                    endTime += ":59";
                }
@@ -312,10 +327,12 @@
                request.setEndtime(endTime);
                request.setTimezone(8); // 中国时区
                logger.info("查询车辆轨迹:车辆号:{}, 设备ID:{}, 开始时间:{}, 结束时间:{}", vehicleNo, vehicleInfo.getDeviceId(), beginTime, endTime);
                // 查询轨迹
                GpsTrackQueryResponse response = gpsCollectService.queryTracks(request);
                if (response.getStatus() != 0) {
                    throw new Error("查询轨迹失败:" + response.getCause());
                    logger.error("查询轨迹失败,状态码:{}, 错误信息:{}", response.getStatus(), response.getCause());
                    throw new Error("查询轨迹失败:" + (response.getCause() != null ? response.getCause() : "未知错误"));
                }
                // 转换GPS51轨迹点为统一格式
@@ -364,4 +381,222 @@
            throw new Error("查询车辆轨迹失败:" + e.getMessage());
        }
    }
}
    /**
     * 腾讯地图地址搜索接口代理
     */
    @Anonymous()
    @GetMapping("/address/search")
    public AjaxResult searchAddress(String keyword, String region) {
        try {
            // 构建腾讯地图搜索API URL
            String url = "https://apis.map.qq.com/ws/place/v1/search";
            String params = "keyword=" + URLEncoder.encode(keyword, StandardCharsets.UTF_8.toString()) +
                           "&boundary=region(" + (region != null ? region : "广州") + ")" +
                           "&key=" + tencentMapConfig.getKey();
            // 发送HTTP请求
            String response = HttpUtils.sendGet(url, params);
            // 返回结果
            return AjaxResult.success("查询成功", response);
        } catch (Exception e) {
            logger.error("地址搜索失败", e);
            return AjaxResult.error("地址搜索失败:" + e.getMessage());
        }
    }
    /**
     * 腾讯地图逆地址解析接口代理
     */
    @Anonymous()
    @GetMapping("/address/geocoder")
    public AjaxResult reverseGeocoder(Double lat, Double lng) {
        try {
            // 检查参数
            logger.info("逆地址解析请求参数: lat={}, lng={}", lat, lng);
            if (lat == null || lng == null) {
                logger.warn("参数不完整,缺少经纬度坐标: lat={}, lng={}", lat, lng);
                return AjaxResult.error("参数不完整,缺少经纬度坐标");
            }
            // 检查参数有效性
            if (Double.isNaN(lat) || Double.isNaN(lng) ||
                Double.isInfinite(lat) || Double.isInfinite(lng)) {
                logger.warn("参数无效,经纬度坐标包含非法值: lat={}, lng={}", lat, lng);
                return AjaxResult.error("参数无效,经纬度坐标格式错误");
            }
            // 构建腾讯地图逆地址解析API URL
            String url = "https://apis.map.qq.com/ws/geocoder/v1/";
            String params = "location=" + lat + "," + lng +
                           "&key=" + tencentMapConfig.getKey() +
                           "&get_poi=1";
            // 发送HTTP请求
            String response = HttpUtils.sendGet(url, params);
            // 返回结果
            return AjaxResult.success("查询成功", response);
        } catch (Exception e) {
            logger.error("逆地址解析失败: lat={}, lng={}", lat, lng, e);
            return AjaxResult.error("逆地址解析失败:" + e.getMessage());
        }
    }
    /**
     * 腾讯地图路线规划接口代理(计算两点间距离)
     */
    @Anonymous()
    @GetMapping("/route/distance")
    public AjaxResult calculateDistance(Double fromLat, Double fromLng, Double toLat, Double toLng) {
        try {
            // 检查参数
            if (fromLat == null || fromLng == null || toLat == null || toLng == null) {
                return AjaxResult.error("参数不完整,缺少起点或终点坐标");
            }
            // 构建腾讯地图路线规划API URL
            String url = "https://apis.map.qq.com/ws/distance/v1/";
            String params = "mode=driving" +
                           "&from=" + fromLat + "," + fromLng +
                           "&to=" + toLat + "," + toLng +
                           "&key=" + tencentMapConfig.getKey();
            // 发送HTTP请求
            String response = HttpUtils.sendGet(url, params);
            // 返回结果
            return AjaxResult.success("计算成功", response);
        } catch (Exception e) {
            logger.error("距离计算失败", e);
            return AjaxResult.error("距离计算失败:" + e.getMessage());
        }
    }
    /**
     * 百度地图地理编码接口代理(地址转坐标)
     */
    @Anonymous()
    @GetMapping("/baidu/geocoding")
    public AjaxResult baiduGeocoding(String address, String city) {
        try {
            // 检查参数
            if (address == null || address.trim().isEmpty()) {
                return AjaxResult.error("参数不完整,缺少地址信息");
            }
            // 构建百度地图地理编码API URL
            String url = "https://api.map.baidu.com/geocoding/v3/";
            String params = "address=" + URLEncoder.encode(address, StandardCharsets.UTF_8.toString()) +
                           (city != null && !city.trim().isEmpty() ?
                            "&city=" + URLEncoder.encode(city, StandardCharsets.UTF_8.toString()) : "") +
                           "&output=json" +
                           "&ak=" + baiduMapConfig.getAk();
            logger.info("百度地图地理编码请求: address={}, city={}", address, city);
            // 发送HTTP请求
            String response = HttpUtils.sendGet(url, params);
            // 返回结果
            return AjaxResult.success("查询成功", response);
        } catch (Exception e) {
            logger.error("百度地图地理编码失败", e);
            return AjaxResult.error("地理编码失败:" + e.getMessage());
        }
    }
    /**
     * 百度地图路线规划接口代理(计算两个坐标之间的驾车距离)
     */
    @Anonymous()
    @GetMapping("/baidu/route/driving")
    public AjaxResult baiduRouteDriving(String origin, String destination) {
        try {
            // 检查参数
            if (origin == null || origin.trim().isEmpty() ||
                destination == null || destination.trim().isEmpty()) {
                return AjaxResult.error("参数不完整,缺少起点或终点坐标");
            }
            // 验证坐标格式(纬度,经度)
            String[] originParts = origin.split(",");
            String[] destParts = destination.split(",");
            if (originParts.length != 2 || destParts.length != 2) {
                return AjaxResult.error("坐标格式错误,应为:纬度,经度");
            }
            // 构建百度地图路线规划API URL
            String url = "https://api.map.baidu.com/directionlite/v1/driving";
            String params = "origin=" + origin +
                           "&destination=" + destination +
                           "&ak=" + baiduMapConfig.getAk();
            logger.info("百度地图路线规划请求: origin={}, destination={}", origin, destination);
            // 发送HTTP请求
            String response = HttpUtils.sendGet(url, params);
            // 返回结果
            return AjaxResult.success("计算成功", response);
        } catch (Exception e) {
            logger.error("百度地图路线规划失败", e);
            return AjaxResult.error("路线规划失败:" + e.getMessage());
        }
    }
    /**
     * 百度地图计算两个地址之间的距离(组合接口:地址转坐标 + 路线规划)
     */
    @Anonymous()
    @GetMapping("/baidu/distance/byAddress")
    public AjaxResult baiduDistanceByAddress(String fromAddress, String fromCity,
                                             String toAddress, String toCity) {
        try {
            // 检查参数
            if (fromAddress == null || fromAddress.trim().isEmpty() ||
                toAddress == null || toAddress.trim().isEmpty()) {
                return AjaxResult.error("参数不完整,缺少起点或终点地址");
            }
            logger.info("开始计算地址距离: fromAddress={}, fromCity={}, toAddress={}, toCity={}",
                       fromAddress, fromCity, toAddress, toCity);
            // 第一步:起点地址转坐标
            String geocodingUrl1 = "https://api.map.baidu.com/geocoding/v3/";
            String geocodingParams1 = "address=" + URLEncoder.encode(fromAddress, StandardCharsets.UTF_8.toString()) +
                                     (fromCity != null && !fromCity.trim().isEmpty() ?
                                      "&city=" + URLEncoder.encode(fromCity, StandardCharsets.UTF_8.toString()) : "") +
                                     "&output=json" +
                                     "&ak=" + baiduMapConfig.getAk();
            String geocodingResponse1 = HttpUtils.sendGet(geocodingUrl1, geocodingParams1);
            logger.info("起点地理编码响应: {}", geocodingResponse1);
            // 第二步:终点地址转坐标
            String geocodingUrl2 = "https://api.map.baidu.com/geocoding/v3/";
            String geocodingParams2 = "address=" + URLEncoder.encode(toAddress, StandardCharsets.UTF_8.toString()) +
                                     (toCity != null && !toCity.trim().isEmpty() ?
                                      "&city=" + URLEncoder.encode(toCity, StandardCharsets.UTF_8.toString()) : "") +
                                     "&output=json" +
                                     "&ak=" + baiduMapConfig.getAk();
            String geocodingResponse2 = HttpUtils.sendGet(geocodingUrl2, geocodingParams2);
            logger.info("终点地理编码响应: {}", geocodingResponse2);
            // 解析坐标(这里简化处理,实际应该解析JSON)
            // 注意:需要从响应中提取坐标,这里返回中间结果供前端处理
            Map<String, Object> result = new HashMap<>();
            result.put("fromGeocoding", geocodingResponse1);
            result.put("toGeocoding", geocodingResponse2);
            result.put("message", "请解析坐标后调用 /baidu/route/driving 接口计算距离");
            return AjaxResult.success("地理编码成功", result);
        } catch (Exception e) {
            logger.error("计算地址距离失败", e);
            return AjaxResult.error("计算距离失败:" + e.getMessage());
        }
    }
}