package com.ruoyi.web.controller.system;
|
|
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;
|
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RestController;
|
|
import com.ruoyi.common.annotation.Anonymous;
|
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
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
|
*/
|
@RestController
|
@RequestMapping("/system/gps")
|
public class VehicleGpsController extends BaseController {
|
@Autowired
|
private IVehicleGpsService vehicleGpsService;
|
|
@Autowired
|
private ITbVehicleOrderService tbVehicleOrderService;
|
|
@Autowired
|
private IDispatchOrdService dispatchOrdService;
|
|
@Autowired
|
private ITbOrdersService tbOrdersService;
|
|
@Autowired
|
private IGpsCollectService gpsCollectService;
|
|
@Autowired
|
private IVehicleInfoService vehicleInfoService;
|
|
@Autowired
|
private ICmsGpsCollectService cmsGpsCollectService;
|
|
@Autowired
|
private TencentMapConfig tencentMapConfig;
|
|
@Autowired
|
private BaiduMapConfig baiduMapConfig;
|
|
/**
|
* 查询车辆GPS坐标列表
|
*/
|
@PreAuthorize("@ss.hasPermi('system:gps:list')")
|
@GetMapping("/list")
|
public TableDataInfo list(VehicleGps vehicleGps) {
|
|
startPage();
|
// String vehicleNo=vehicleGps.getVehicleNo();
|
// String beginTime=vehicleGps.getBeginTime();
|
// String endTime=vehicleGps.getEndTime();
|
// return this.getAnonymousTracks(vehicleNo,beginTime,endTime);
|
//
|
// // 设置按时间倒序排序
|
vehicleGps.setOrderByColumn("collect_time");
|
vehicleGps.setIsAsc("desc");
|
List<VehicleGps> list = vehicleGpsService.selectVehicleGpsList(vehicleGps);
|
return getDataTable(list);
|
}
|
@Anonymous(needSign=true)
|
@GetMapping("/anonymousList")
|
public TableDataInfo anonymousList(VehicleGps vehicleGps) {
|
|
if(vehicleGps.getOrderId()==null)
|
{
|
return getDataTable(new ArrayList<>());
|
}
|
|
//查询订单
|
TbVehicleOrder tbVehicleOrder = tbVehicleOrderService.selectTbVehicleOrderById(vehicleGps.getOrderId());
|
if(tbVehicleOrder==null)
|
{
|
return getDataTable(new ArrayList<>());
|
}
|
|
if(!Objects.equals(tbVehicleOrder.getStatus(), "0"))
|
{
|
//非0表示订单完成了。
|
try {
|
TbOrders tbOrders = tbOrdersService.selectTbOrdersByOrderID(vehicleGps.getOrderId());
|
if (tbOrders == null) {
|
return getDataTable(new ArrayList<>());
|
}
|
|
|
DispatchOrd dispatchOrd = dispatchOrdService.selectDispatchOrdByServiceOrdIDDt(tbOrders.getServiceOrdID());
|
if (dispatchOrd == null) {
|
return getDataTable(new ArrayList<>());
|
}
|
|
String vehicleNo = tbVehicleOrder.getVehicle();
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
String beginTime= sdf.format(dispatchOrd.getDispatchOrdStartDate());
|
String endTime= sdf.format(dispatchOrd.getDispatchOrdUpdateTime());
|
//如果订单没完成, endTime为当前时间;如何订单已经完成了,用订单的结束时间。
|
|
return this.getAnonymousTracks(vehicleNo,beginTime,endTime);
|
// Map<String, Object> params = new HashMap<>();
|
// params.put("beginTime", dispatchOrd.getDispatchOrdStartDate());
|
// params.put("endTime", dispatchOrd.getDispatchOrdUpdateTime());
|
//
|
// vehicleGps.setVehicleNo(tbVehicleOrder.getVehicle());
|
// startPage();
|
// // 设置按时间倒序排序
|
// vehicleGps.setOrderByColumn("collect_time");
|
// vehicleGps.setIsAsc("desc");
|
// List<VehicleGps> list = vehicleGpsService.selectVehicleGpsList(vehicleGps);
|
// return getDataTable(list);
|
}
|
catch (Exception ex)
|
{
|
logger.error("已完成的订单查询地图异常:{}",ex.getMessage());
|
return getDataTable(new ArrayList<>());
|
}
|
}else{
|
TbOrders tbOrders = tbOrdersService.selectTbOrdersByOrderID(vehicleGps.getOrderId());
|
if (tbOrders == null) {
|
return getDataTable(new ArrayList<>());
|
}
|
DispatchOrd dispatchOrd = dispatchOrdService.selectDispatchOrdByServiceOrdIDDt(tbOrders.getServiceOrdID());
|
if (dispatchOrd == null) {
|
return getDataTable(new ArrayList<>());
|
}
|
String vehicleNo = tbVehicleOrder.getVehicle();
|
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());
|
// startPage();
|
// // 设置按时间倒序排序
|
// vehicleGps.setOrderByColumn("collect_time");
|
// vehicleGps.setIsAsc("desc");
|
// List<VehicleGps> list = vehicleGpsService.selectVehicleGpsList(vehicleGps);
|
// return getDataTable(list);
|
}
|
}
|
|
/**
|
* 导出车辆GPS坐标列表
|
*/
|
@PreAuthorize("@ss.hasPermi('system:gps:export')")
|
@Log(title = "车辆GPS坐标", businessType = BusinessType.EXPORT)
|
@GetMapping("/export")
|
public AjaxResult export(VehicleGps vehicleGps) {
|
// 设置按时间倒序排序
|
vehicleGps.setOrderByColumn("collect_time");
|
vehicleGps.setIsAsc("desc");
|
List<VehicleGps> list = vehicleGpsService.selectVehicleGpsList(vehicleGps);
|
ExcelUtil<VehicleGps> util = new ExcelUtil<VehicleGps>(VehicleGps.class);
|
return util.exportExcel(list, "车辆GPS坐标数据");
|
}
|
|
/**
|
* 获取车辆GPS坐标详细信息
|
*/
|
@PreAuthorize("@ss.hasPermi('system:gps:query')")
|
@GetMapping(value = "/{gpsId}")
|
public AjaxResult getInfo(@PathVariable("gpsId") Long gpsId) {
|
return success(vehicleGpsService.selectVehicleGpsById(gpsId));
|
}
|
|
/**
|
* 新增车辆GPS坐标
|
*/
|
@PreAuthorize("@ss.hasPermi('system:gps:add')")
|
@Log(title = "车辆GPS坐标", businessType = BusinessType.INSERT)
|
@PostMapping
|
public AjaxResult add(@RequestBody VehicleGps vehicleGps) {
|
return toAjax(vehicleGpsService.insertVehicleGps(vehicleGps));
|
}
|
|
/**
|
* 修改车辆GPS坐标
|
*/
|
@PreAuthorize("@ss.hasPermi('system:gps:edit')")
|
@Log(title = "车辆GPS坐标", businessType = BusinessType.UPDATE)
|
@PutMapping
|
public AjaxResult edit(@RequestBody VehicleGps vehicleGps) {
|
return toAjax(vehicleGpsService.updateVehicleGps(vehicleGps));
|
}
|
|
/**
|
* 删除车辆GPS坐标
|
*/
|
@PreAuthorize("@ss.hasPermi('system:gps:remove')")
|
@Log(title = "车辆GPS坐标", businessType = BusinessType.DELETE)
|
@DeleteMapping("/{gpsIds}")
|
public AjaxResult remove(@PathVariable Long[] gpsIds) {
|
return toAjax(vehicleGpsService.deleteVehicleGpsByIds(gpsIds));
|
}
|
|
/**
|
* 查询车辆历史轨迹
|
*/
|
@PreAuthorize("@ss.hasPermi('system:gps:query')")
|
@GetMapping("/tracks")
|
public TableDataInfo getTracks(String vehicleNo, String beginTime, String endTime) {
|
return getAnonymousTracks(vehicleNo, beginTime, endTime);
|
}
|
|
|
/**
|
* 匿名查询车辆历史轨迹
|
*/
|
@Anonymous()
|
@GetMapping("/anonymousTracks")
|
public TableDataInfo getAnonymousTracks(String vehicleNo, String beginTime, String endTime) {
|
try {
|
// 通过车牌号获取设备ID
|
VehicleInfo vehicleInfo = vehicleInfoService.selectVehicleInfoByPlateNumber(vehicleNo);
|
if (vehicleInfo == null) {
|
|
// throw new Error("未找到该车辆对应的GPS设备");
|
return getDataTable(new ArrayList<>());
|
}
|
|
// 处理开始时间
|
beginTime = beginTime.replace("T", " ");
|
if (beginTime.split(":").length == 2) { // 只有小时和分钟
|
beginTime += ":00";
|
}
|
|
// 处理结束时间
|
// endTime = endTime.replace("T", " ").replace(" ","%20");
|
endTime = endTime.replace("T", " ");
|
if (endTime.split(":").length == 2) { // 只有小时和分钟
|
endTime += ":59";
|
}
|
|
List<GpsTrackPoint> trackPoints = new ArrayList<>();
|
|
//如果平台是cms,则调用cms的接口
|
if(vehicleInfo.getPlatformCode().equals("CMS"))
|
{
|
|
CmsTrackDetailResponse response = cmsGpsCollectService.queryTrackDetail(
|
vehicleInfo.getDeviceId(), // 设备号
|
beginTime, // 开始时间
|
endTime, // 结束时间
|
null, // 距离(可选)
|
null, // 停车时长(可选)
|
1, // 解析地理位置
|
null, // 当前页码(可选)
|
null, // 每页记录数(可选)
|
2 // 地图类型(2:百度地图)
|
);
|
|
if (response.getResult() != 0) {
|
throw new Error("查询CMS轨迹失败");
|
}
|
|
// 转换CMS轨迹点为统一格式
|
if (response.getTracks() != null) {
|
for (CmsTrackDetailResponse.CmsTrackPoint point : response.getTracks()) {
|
GpsTrackPoint trackPoint = new GpsTrackPoint();
|
trackPoint.setVehicleNo(point.getVid());
|
trackPoint.setDeviceId(point.getId());
|
|
//经度纬度为空时,跳过
|
if(point.getMlng()==null || point.getMlat()==null)
|
{
|
continue;
|
}
|
|
// 经度,使用三元运算符
|
trackPoint.setLongitude(point.getMlng() != null ? Double.parseDouble(point.getMlng()) : 0.0);
|
|
// 纬度,使用三元运算符
|
trackPoint.setLatitude(point.getMlat() != null ? Double.parseDouble(point.getMlat()) : 0.0);
|
|
// 速度,直接使用int转double
|
trackPoint.setSpeed(point.getSp() > 0 ? (double)point.getSp() : 0.0);
|
|
// 方向,使用三元运算符处理
|
trackPoint.setCourse(point.getFt() > 0 ? point.getFt() : 0);
|
|
// ACC状态,使用三元运算符处理
|
trackPoint.setAccStatus(point.getAc() > 0 ? point.getAc() : 0);
|
|
// 在线状态,使用三元运算符处理
|
trackPoint.setOnlineStatus(point.getNet() > 0 ? point.getNet() : 0);
|
trackPoint.setAddress(point.getPs());
|
|
// 上报时间,直接使用字符串
|
trackPoint.setReportTime(point.getGt() != null ? point.getGt() : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
|
trackPoints.add(trackPoint);
|
}
|
}
|
}
|
else {
|
|
// 构建查询请求
|
GpsTrackQueryRequest request = new GpsTrackQueryRequest();
|
request.setDeviceid(vehicleInfo.getDeviceId());
|
request.setBegintime(beginTime);
|
request.setEndtime(endTime);
|
request.setTimezone(8); // 中国时区
|
|
logger.info("查询车辆轨迹:车辆号:{}, 设备ID:{}, 开始时间:{}, 结束时间:{}", vehicleNo, vehicleInfo.getDeviceId(), beginTime, endTime);
|
// 查询轨迹
|
GpsTrackQueryResponse response = gpsCollectService.queryTracks(request);
|
if (response.getStatus() != 0) {
|
logger.error("查询轨迹失败,状态码:{}, 错误信息:{}", response.getStatus(), response.getCause());
|
throw new Error("查询轨迹失败:" + (response.getCause() != null ? response.getCause() : "未知错误"));
|
}
|
|
// 转换GPS51轨迹点为统一格式
|
if (response.getRecords() != null) {
|
for (GpsTrackPoint point : response.getRecords()) {
|
GpsTrackPoint trackPoint = new GpsTrackPoint();
|
trackPoint.setVehicleNo(vehicleNo);
|
trackPoint.setDeviceId(vehicleInfo.getDeviceId());
|
trackPoint.setLongitude(point.getLongitude()); // 经度
|
trackPoint.setLatitude(point.getLatitude()); // 纬度
|
trackPoint.setSpeed(point.getSpeed()); // 速度
|
trackPoint.setCourse(point.getCourse()); // 方向
|
trackPoint.setReportTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(point.getUpdatetime()))); // 上报时间
|
trackPoints.add(trackPoint);
|
}
|
}
|
}
|
//转换成List<VehicleGps>
|
List<VehicleGps> vehicleGpsList = new ArrayList<>();
|
for(GpsTrackPoint trackPoint : trackPoints)
|
{
|
VehicleGps vehicleGps = new VehicleGps();
|
vehicleGps.setVehicleNo(trackPoint.getVehicleNo());
|
vehicleGps.setDeviceId(trackPoint.getDeviceId());
|
vehicleGps.setLongitude(trackPoint.getLongitude());
|
vehicleGps.setLatitude(trackPoint.getLatitude());
|
vehicleGps.setSpeed(trackPoint.getSpeed());
|
//方向
|
vehicleGps.setDirection(Double.valueOf(trackPoint.getCourse()));
|
//地址
|
vehicleGps.setAddress(trackPoint.getAddress());
|
vehicleGps.setCollectTime(trackPoint.getReportTime());
|
//GPS平台处理时间
|
vehicleGps.setPlatformProcessTime(trackPoint.getReportTime());
|
vehicleGps.setDeviceReportTime(trackPoint.getReportTime());
|
vehicleGpsList.add(vehicleGps);
|
}
|
//时间倒序排序
|
vehicleGpsList.sort(Comparator.comparing(VehicleGps::getDeviceReportTime).reversed());
|
|
//返回车辆Gps列表
|
return getDataTable(vehicleGpsList);
|
// return success(vehicleGpsList);
|
} catch (Exception e) {
|
logger.error("查询车辆轨迹异常", e);
|
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);
|
|
// 解析起点坐标
|
com.alibaba.fastjson2.JSONObject geocodingJson1 = com.alibaba.fastjson2.JSONObject.parseObject(geocodingResponse1);
|
if (geocodingJson1.getInteger("status") != 0) {
|
logger.error("起点地理编码失败: {}", geocodingResponse1);
|
return AjaxResult.error("起点地址解析失败");
|
}
|
com.alibaba.fastjson2.JSONObject location1 = geocodingJson1.getJSONObject("result").getJSONObject("location");
|
double fromLat = location1.getDouble("lat");
|
double fromLng = location1.getDouble("lng");
|
logger.info("起点坐标: lat={}, lng={}", fromLat, fromLng);
|
|
// 第二步:终点地址转坐标
|
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);
|
|
// 解析终点坐标
|
com.alibaba.fastjson2.JSONObject geocodingJson2 = com.alibaba.fastjson2.JSONObject.parseObject(geocodingResponse2);
|
if (geocodingJson2.getInteger("status") != 0) {
|
logger.error("终点地理编码失败: {}", geocodingResponse2);
|
return AjaxResult.error("终点地址解析失败");
|
}
|
com.alibaba.fastjson2.JSONObject location2 = geocodingJson2.getJSONObject("result").getJSONObject("location");
|
double toLat = location2.getDouble("lat");
|
double toLng = location2.getDouble("lng");
|
logger.info("终点坐标: lat={}, lng={}", toLat, toLng);
|
|
// 第三步:调用路线规划接口计算距离
|
String routeUrl = "https://api.map.baidu.com/directionlite/v1/driving";
|
String origin = fromLat + "," + fromLng;
|
String destination = toLat + "," + toLng;
|
String routeParams = "origin=" + origin +
|
"&destination=" + destination +
|
"&ak=" + baiduMapConfig.getAk();
|
|
logger.info("路线规划请求: origin={}, destination={}", origin, destination);
|
String routeResponse = HttpUtils.sendGet(routeUrl, routeParams);
|
logger.info("路线规划响应: {}", routeResponse);
|
|
// 解析距离结果
|
com.alibaba.fastjson2.JSONObject routeJson = com.alibaba.fastjson2.JSONObject.parseObject(routeResponse);
|
if (routeJson.getInteger("status") != 0) {
|
logger.error("路线规划失败: {}", routeResponse);
|
return AjaxResult.error("路线规划失败");
|
}
|
|
// 提取距离信息(单位:米)
|
com.alibaba.fastjson2.JSONObject result = routeJson.getJSONObject("result");
|
com.alibaba.fastjson2.JSONArray routes = result.getJSONArray("routes");
|
if (routes == null || routes.isEmpty()) {
|
logger.error("未找到路线信息");
|
return AjaxResult.error("未找到路线信息");
|
}
|
|
com.alibaba.fastjson2.JSONObject route = routes.getJSONObject(0);
|
int distance = route.getInteger("distance"); // 距离,单位:米
|
int duration = route.getInteger("duration"); // 时长,单位:秒
|
|
logger.info("计算成功: 距离={}米, 时长={}秒", distance, duration);
|
|
// 构建返回结果
|
Map<String, Object> resultMap = new HashMap<>();
|
resultMap.put("distance", distance); // 距离(米)
|
resultMap.put("duration", duration); // 时长(秒)
|
resultMap.put("distanceKm", String.format("%.1f", distance / 1000.0)); // 距离(公里)
|
resultMap.put("durationMin", duration / 60); // 时长(分钟)
|
|
// 起点坐标
|
Map<String, Object> fromLocation = new HashMap<>();
|
fromLocation.put("lat", fromLat);
|
fromLocation.put("lng", fromLng);
|
resultMap.put("fromLocation", fromLocation);
|
|
// 终点坐标
|
Map<String, Object> toLocation = new HashMap<>();
|
toLocation.put("lat", toLat);
|
toLocation.put("lng", toLng);
|
resultMap.put("toLocation", toLocation);
|
|
return AjaxResult.success("计算成功", resultMap);
|
} catch (Exception e) {
|
logger.error("计算地址距离失败", e);
|
return AjaxResult.error("计算距离失败:" + e.getMessage());
|
}
|
}
|
|
/**
|
* 百度地图地址搜索提示API(输入联想)
|
* Place Suggestion API - 用于地址输入时的智能提示
|
*/
|
@Anonymous()
|
@GetMapping("/baidu/place/suggestion")
|
public AjaxResult baiduPlaceSuggestion(String query, String region) {
|
try {
|
// 检查参数
|
if (query == null || query.trim().isEmpty()) {
|
return AjaxResult.error("参数不完整,缺少搜索关键词");
|
}
|
|
// 构建百度地图 Place Suggestion API URL
|
String url = "https://api.map.baidu.com/place/v2/suggestion";
|
String params = "query=" + URLEncoder.encode(query, StandardCharsets.UTF_8.toString()) +
|
(region != null && !region.trim().isEmpty() ?
|
"®ion=" + URLEncoder.encode(region, StandardCharsets.UTF_8.toString()) : "") +
|
"&output=json" +
|
"&ak=" + baiduMapConfig.getAk();
|
|
logger.info("百度地图地址搜索提示请求: query={}, region={}", query, region);
|
|
// 发送HTTP请求
|
String response = HttpUtils.sendGet(url, params);
|
logger.debug("百度地图地址搜索提示响应: {}", response);
|
|
// 解析响应
|
com.alibaba.fastjson2.JSONObject jsonResponse = com.alibaba.fastjson2.JSONObject.parseObject(response);
|
if (jsonResponse.getInteger("status") != 0) {
|
logger.error("地址搜索提示失败: {}", response);
|
return AjaxResult.error("地址搜索失败");
|
}
|
|
// 提取提示列表
|
com.alibaba.fastjson2.JSONArray results = jsonResponse.getJSONArray("result");
|
if (results == null || results.isEmpty()) {
|
logger.info("未找到匹配的地址");
|
return AjaxResult.success("查询成功", new ArrayList<>());
|
}
|
|
// 构建返回结果
|
List<Map<String, Object>> suggestions = new ArrayList<>();
|
for (int i = 0; i < results.size(); i++) {
|
com.alibaba.fastjson2.JSONObject item = results.getJSONObject(i);
|
|
Map<String, Object> suggestion = new HashMap<>();
|
suggestion.put("name", item.getString("name")); // 名称
|
suggestion.put("address", item.getString("address")); // 地址
|
suggestion.put("province", item.getString("province")); // 省
|
suggestion.put("city", item.getString("city")); // 市
|
suggestion.put("district", item.getString("district")); // 区
|
suggestion.put("uid", item.getString("uid")); // 地点UID
|
|
// 经纬度信息
|
com.alibaba.fastjson2.JSONObject location = item.getJSONObject("location");
|
if (location != null) {
|
Map<String, Object> locationMap = new HashMap<>();
|
locationMap.put("lat", location.getDouble("lat"));
|
locationMap.put("lng", location.getDouble("lng"));
|
suggestion.put("location", locationMap);
|
}
|
|
suggestions.add(suggestion);
|
}
|
|
logger.info("地址搜索提示成功: 找到{} 条结果", suggestions.size());
|
return AjaxResult.success("查询成功", suggestions);
|
} catch (Exception e) {
|
logger.error("地址搜索提示失败", e);
|
return AjaxResult.error("地址搜索失败:" + e.getMessage());
|
}
|
}
|
}
|