From fc1210499883d6f941b5a80aaba4dab717b9c0af Mon Sep 17 00:00:00 2001 From: xiepufeng <1072271977@qq.com> Date: Mon, 3 Jun 2024 11:15:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=A4=E9=80=9A=E6=B5=81=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DcTrafficStatisticsController.java | 86 +++ .../business/domain/DcCongestionSection.java | 26 + .../domain/DcRoadSectionCongestion.java | 35 ++ .../IDcTollStationStatisticsDataService.java | 6 + .../IDcTrafficSectionStatisticsService.java | 2 + .../service/IDcTrafficStatisticsService.java | 30 ++ .../impl/DcTollStationStatisticsDataImpl.java | 103 +++- .../impl/DcTrafficStatisticsServiceImpl.java | 492 +++++++++++++++++- 8 files changed, 775 insertions(+), 5 deletions(-) create mode 100644 zc-business/src/main/java/com/zc/business/domain/DcCongestionSection.java create mode 100644 zc-business/src/main/java/com/zc/business/domain/DcRoadSectionCongestion.java diff --git a/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java b/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java index 89327486..cb2eb3a4 100644 --- a/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java +++ b/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java @@ -1,5 +1,6 @@ package com.zc.business.controller; +import com.alibaba.fastjson.JSONArray; import com.ruoyi.common.core.domain.AjaxResult; import com.zc.business.domain.*; import com.zc.business.request.DcTrafficMetricsDataRequest; @@ -8,12 +9,15 @@ import com.zc.business.service.IDcGantryStatisticsDataService; import com.zc.business.service.IDcTollStationStatisticsDataService; import com.zc.business.service.IDcTrafficSectionStatisticsService; import com.zc.business.service.IDcTrafficStatisticsService; +import com.zc.common.core.httpclient.exception.HttpException; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import java.io.IOException; import java.util.List; +import java.util.Map; /** * 交通数据统计 @@ -146,6 +150,21 @@ public class DcTrafficStatisticsController { return AjaxResult.success(dcStatisticsData); } + /** + * 获取累计车流量 + * + * @param request 包含查询条件的请求对象,用于筛选历史收费站统计数据 + * @return 返回一个AjaxResult对象,其中包含了查询到的收费站统计数据列表 + */ + @ApiOperation("获取累计车流量") + @GetMapping("/history/accumulated-flow") + public AjaxResult accumulatedFlow(DcTollStationStatisticsData request){ + // 调用服务层方法,根据请求条件查询历史车收费站数据 + List dcStatisticsData = dcTollStationStatisticsDataService.accumulatedFlow(request); + // 将查询结果封装为成功响应并返回 + return AjaxResult.success(dcStatisticsData); + } + /** * 获取门架统计数据 * @@ -162,4 +181,71 @@ public class DcTrafficStatisticsController { } + /********************************************* 智慧高速平接口 **************************************************/ + + + /** + * 获取在途车辆流量(分车型) + * 该接口不接受任何参数,调用后返回在途车辆的统计数据,数据格式为JSONObject。 + * + * @return AjaxResult 返回类型为AjaxResult,其中包含了操作结果和在途车辆统计数据的JSONObject。 + */ + @ApiOperation("获取在途车辆流量(分车型)") + @GetMapping("/current/in-transit-vehicles") + public AjaxResult vehiclesInTransit() throws HttpException, IOException { + // 调用服务层方法,获取在途车辆的统计数据 + JSONArray dcStatisticsData = dcTrafficStatisticsService.vehiclesInTransit(); + return AjaxResult.success(dcStatisticsData); + } + + @ApiOperation("获取在途车路段平均车速") + @GetMapping("/current/average-speed") + public AjaxResult currentAverageSpeed() throws HttpException, IOException { + // 调用服务层方法,获取在途车辆的统计数据 + JSONArray dcStatisticsData = dcTrafficStatisticsService.currentAverageSpeed(); + return AjaxResult.success(dcStatisticsData); + } + + /** + * 获取当前拥堵事件信息(智慧高速平台) + * + * @return 返回一个AjaxResult对象,其中包含了查询结果。如果查询成功,则结果中封装了当前拥堵路段的数据列表。 + */ + @ApiOperation("获取当前拥堵事件信息") + @GetMapping("/current/event-congested") + public AjaxResult currentEventCongested() throws HttpException, IOException { + // 调用服务层方法,获取当前交通指标数据 + JSONArray jsonArray = dcTrafficStatisticsService.currentEventCongested(); + // 将获取到的交通指标数据封装为成功的结果并返回 + return AjaxResult.success(jsonArray); + } + + /** + * 获取当前拥堵路段信息 + * + * @return 返回一个AjaxResult对象,其中包含了查询结果。如果查询成功,则结果中封装了当前拥堵路段的数据列表。 + */ + @ApiOperation("获取当前路段拥堵信息") + @GetMapping("/current/section-congested") + public AjaxResult currentSectionCongested() throws HttpException, IOException { + // 调用服务层方法,获取当前交通指标数据 + List roadSectionCongestions = dcTrafficStatisticsService.currentSectionCongested(); + // 将获取到的交通指标数据封装为成功的结果并返回 + return AjaxResult.success(roadSectionCongestions); + } + + /** + * 获取车道占有率信息 + * + */ + @ApiOperation("获取车道占有率信息") + @GetMapping("/history/lane-occupancy") + public AjaxResult laneOccupancy(String startDate, String endDate) throws HttpException, IOException { + // 调用服务层方法,获取当前交通指标数据 + JSONArray jsonArray = dcTrafficStatisticsService.laneOccupancy(startDate, endDate); + // 将获取到的交通指标数据封装为成功的结果并返回 + return AjaxResult.success(jsonArray); + } + + } diff --git a/zc-business/src/main/java/com/zc/business/domain/DcCongestionSection.java b/zc-business/src/main/java/com/zc/business/domain/DcCongestionSection.java new file mode 100644 index 00000000..02ebd9d5 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/domain/DcCongestionSection.java @@ -0,0 +1,26 @@ +package com.zc.business.domain; + +import lombok.Data; + +@Data +public class DcCongestionSection { + /** + * 拥堵状态 + */ + private int congestionStatus; + + /** + * 拥堵开始桩号 + */ + private Integer congestionStartStakeMark; + + /** + * 拥堵结束桩号 + */ + private Integer congestionEndStakeMark; + + /** + * 拥堵距离(米) + */ + private int congestionDistance; +} diff --git a/zc-business/src/main/java/com/zc/business/domain/DcRoadSectionCongestion.java b/zc-business/src/main/java/com/zc/business/domain/DcRoadSectionCongestion.java new file mode 100644 index 00000000..69e5963f --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/domain/DcRoadSectionCongestion.java @@ -0,0 +1,35 @@ +package com.zc.business.domain; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * 路段拥堵信息 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class DcRoadSectionCongestion extends DcRoadSection { + + private static final long serialVersionUID = 1L; + + /** + * 上行拥堵路段 + */ + private List upCongestionSections; + + /** + * 下行拥堵路段 + */ + private List downCongestionSections; + + /** + * 拥堵状态 + */ + private int congestionStatus; +} + + + + diff --git a/zc-business/src/main/java/com/zc/business/service/IDcTollStationStatisticsDataService.java b/zc-business/src/main/java/com/zc/business/service/IDcTollStationStatisticsDataService.java index 41322a2f..eeb3a043 100644 --- a/zc-business/src/main/java/com/zc/business/service/IDcTollStationStatisticsDataService.java +++ b/zc-business/src/main/java/com/zc/business/service/IDcTollStationStatisticsDataService.java @@ -1,5 +1,6 @@ package com.zc.business.service; +import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.extension.service.IService; import com.zc.business.domain.DcStatisticsData; import com.zc.business.domain.DcTollStationStatisticsData; @@ -33,4 +34,9 @@ public interface IDcTollStationStatisticsDataService extends IService tollStationData(DcTollStationStatisticsData request); + + /** + * 累计车流量 + */ + List accumulatedFlow(DcTollStationStatisticsData request); } diff --git a/zc-business/src/main/java/com/zc/business/service/IDcTrafficSectionStatisticsService.java b/zc-business/src/main/java/com/zc/business/service/IDcTrafficSectionStatisticsService.java index 2adf13ce..c8b47b2f 100644 --- a/zc-business/src/main/java/com/zc/business/service/IDcTrafficSectionStatisticsService.java +++ b/zc-business/src/main/java/com/zc/business/service/IDcTrafficSectionStatisticsService.java @@ -1,5 +1,6 @@ package com.zc.business.service; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.IService; import com.zc.business.domain.DcCongestedSectionData; @@ -63,4 +64,5 @@ public interface IDcTrafficSectionStatisticsService extends IService currentCongestedSection(Byte direction); + } diff --git a/zc-business/src/main/java/com/zc/business/service/IDcTrafficStatisticsService.java b/zc-business/src/main/java/com/zc/business/service/IDcTrafficStatisticsService.java index 1aa57d26..cb272e49 100644 --- a/zc-business/src/main/java/com/zc/business/service/IDcTrafficStatisticsService.java +++ b/zc-business/src/main/java/com/zc/business/service/IDcTrafficStatisticsService.java @@ -1,8 +1,13 @@ package com.zc.business.service; +import com.alibaba.fastjson.JSONArray; +import com.zc.business.domain.DcRoadSectionCongestion; import com.zc.business.domain.DcStatisticsData; +import com.zc.common.core.httpclient.exception.HttpException; +import java.io.IOException; import java.util.List; +import java.util.Map; public interface IDcTrafficStatisticsService { @@ -13,4 +18,29 @@ public interface IDcTrafficStatisticsService { * @return 返回一个DcStatisticsData列表。 */ List historyFlow(DcStatisticsData request); + + /** + * 获取在途车辆流量(分车型) + */ + JSONArray vehiclesInTransit() throws HttpException, IOException; + + /** + * 在途车路段门架平均车速 + */ + JSONArray currentAverageSpeed() throws IOException, HttpException; + + /** + * 获取当前拥堵事件信息 + */ + JSONArray currentEventCongested() throws IOException, HttpException; + + /** + * 路段拥堵信息 + */ + List currentSectionCongested() throws HttpException, IOException; + + /** + * 获取车道占有率信息 + */ + JSONArray laneOccupancy(String startDate, String endDate) throws HttpException, IOException; } diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcTollStationStatisticsDataImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcTollStationStatisticsDataImpl.java index 7d8042ba..e8555f5d 100644 --- a/zc-business/src/main/java/com/zc/business/service/impl/DcTollStationStatisticsDataImpl.java +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcTollStationStatisticsDataImpl.java @@ -1,6 +1,7 @@ package com.zc.business.service.impl; import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.exception.ServiceException; @@ -21,9 +22,13 @@ import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * 收费站数据统计服务实现类 @@ -106,10 +111,13 @@ public class DcTollStationStatisticsDataImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); + } + private List query(DcTollStationStatisticsData request) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); // 如果请求中包含出入类型,则根据出入类型进行过滤 if (request.getAccessType() != null) { @@ -126,13 +134,100 @@ public class DcTollStationStatisticsDataImpl extends ServiceImpl accumulatedFlow(DcTollStationStatisticsData request) { + + if (request.getStartTime() == null || request.getEndTime() == null) { + throw new ServiceException("开始时间或结束时间不能为空"); + } + + if (request.getPeriodType() == null) { + throw new ServiceException("时段类型不能为空"); + } + + List tollStationStatisticsData = query(request); + + // 使用Stream API按statisticalDate分组并汇总车流量 + Map> groupedTrafficVolume = tollStationStatisticsData.stream() + .collect(Collectors.groupingBy( + // 提取statisticalDate字段并转换为 LocalDate(假设statisticalDate是Date类型,需要转换) + data -> data.getStatisticalDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate() + )); + + List result = new ArrayList<>(); + + groupedTrafficVolume.forEach((date, dataList) -> { + + DcTollStationStatisticsData dcTollStationStatisticsData = new DcTollStationStatisticsData(); + dcTollStationStatisticsData.setTrafficVolume(0); + dcTollStationStatisticsData.setType1PassengerFlow(0); + dcTollStationStatisticsData.setType2PassengerFlow(0); + dcTollStationStatisticsData.setType3PassengerFlow(0); + dcTollStationStatisticsData.setType4PassengerFlow(0); + dcTollStationStatisticsData.setType1TruckFlow(0); + dcTollStationStatisticsData.setType2TruckFlow(0); + dcTollStationStatisticsData.setType3TruckFlow(0); + dcTollStationStatisticsData.setType4TruckFlow(0); + dcTollStationStatisticsData.setType5TruckFlow(0); + dcTollStationStatisticsData.setType6TruckFlow(0); + dcTollStationStatisticsData.setType1SpecialVehicleFlow(0); + dcTollStationStatisticsData.setType2SpecialVehicleFlow(0); + dcTollStationStatisticsData.setType3SpecialVehicleFlow(0); + dcTollStationStatisticsData.setType4SpecialVehicleFlow(0); + dcTollStationStatisticsData.setType5SpecialVehicleFlow(0); + dcTollStationStatisticsData.setType6SpecialVehicleFlow(0); + + for (DcTollStationStatisticsData stationStatisticsData : dataList) { + dcTollStationStatisticsData.setStatisticalDate(stationStatisticsData.getStatisticalDate()); + dcTollStationStatisticsData.setPeriodType(stationStatisticsData.getPeriodType()); + dcTollStationStatisticsData.setTrafficVolume(dcTollStationStatisticsData.getTrafficVolume() + stationStatisticsData.getTrafficVolume()); + dcTollStationStatisticsData.setType1TruckFlow(dcTollStationStatisticsData.getType1TruckFlow() + stationStatisticsData.getType1TruckFlow()); + dcTollStationStatisticsData.setType2TruckFlow(dcTollStationStatisticsData.getType2TruckFlow() + stationStatisticsData.getType2TruckFlow()); + dcTollStationStatisticsData.setType3TruckFlow(dcTollStationStatisticsData.getType3TruckFlow() + stationStatisticsData.getType3TruckFlow()); + dcTollStationStatisticsData.setType4TruckFlow(dcTollStationStatisticsData.getType4TruckFlow() + stationStatisticsData.getType4TruckFlow()); + dcTollStationStatisticsData.setType5TruckFlow(dcTollStationStatisticsData.getType5TruckFlow() + stationStatisticsData.getType5TruckFlow()); + dcTollStationStatisticsData.setType6TruckFlow(dcTollStationStatisticsData.getType6TruckFlow() + stationStatisticsData.getType6TruckFlow()); + + dcTollStationStatisticsData.setType1PassengerFlow(dcTollStationStatisticsData.getType1PassengerFlow() + stationStatisticsData.getType1PassengerFlow()); + dcTollStationStatisticsData.setType2PassengerFlow(dcTollStationStatisticsData.getType2PassengerFlow() + stationStatisticsData.getType2PassengerFlow()); + dcTollStationStatisticsData.setType3PassengerFlow(dcTollStationStatisticsData.getType3PassengerFlow() + stationStatisticsData.getType3PassengerFlow()); + dcTollStationStatisticsData.setType4PassengerFlow(dcTollStationStatisticsData.getType4PassengerFlow() + stationStatisticsData.getType4PassengerFlow()); + + dcTollStationStatisticsData.setType1SpecialVehicleFlow(dcTollStationStatisticsData.getType1SpecialVehicleFlow() + stationStatisticsData.getType1SpecialVehicleFlow()); + dcTollStationStatisticsData.setType2SpecialVehicleFlow(dcTollStationStatisticsData.getType2SpecialVehicleFlow() + stationStatisticsData.getType2SpecialVehicleFlow()); + dcTollStationStatisticsData.setType3SpecialVehicleFlow(dcTollStationStatisticsData.getType3SpecialVehicleFlow() + stationStatisticsData.getType3SpecialVehicleFlow()); + dcTollStationStatisticsData.setType4SpecialVehicleFlow(dcTollStationStatisticsData.getType4SpecialVehicleFlow() + stationStatisticsData.getType4SpecialVehicleFlow()); + dcTollStationStatisticsData.setType5SpecialVehicleFlow(dcTollStationStatisticsData.getType5SpecialVehicleFlow() + stationStatisticsData.getType5SpecialVehicleFlow()); + dcTollStationStatisticsData.setType6SpecialVehicleFlow(dcTollStationStatisticsData.getType6SpecialVehicleFlow() + stationStatisticsData.getType6SpecialVehicleFlow()); + } + + result.add(dcTollStationStatisticsData); + + }); + + return result; + + } /** * 恢复日缓存数据的方法(获取当月收费站站点入口和出口数据)。 diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java index 9c64608c..af3b68d7 100644 --- a/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java @@ -1,14 +1,57 @@ package com.zc.business.service.impl; -import com.zc.business.domain.DcStatisticsData; +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zc.business.domain.*; +import com.zc.business.service.IDcFacilityService; +import com.zc.business.service.IDcRoadSectionService; import com.zc.business.service.IDcTrafficStatisticsService; +import com.zc.business.utils.StakeMarkUtils; +import com.zc.common.core.httpclient.OkHttp; +import com.zc.common.core.httpclient.exception.HttpException; +import com.zc.common.core.httpclient.request.RequestParams; +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.Response; +import okhttp3.ResponseBody; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Service public class DcTrafficStatisticsServiceImpl implements IDcTrafficStatisticsService { + // 智慧高速平台token + private JSONObject token = null; + private final String sysid = "sdgs_it_hs_jihe"; + + private String baseUrl = "http://10.166.139.16:8080"; + + @Resource + private IDcFacilityService facilityService; + + @Resource + private IDcRoadSectionService roadSectionService; + + @Resource + private IDcRoadSectionService dcRoadSectionService; + + @PostConstruct + public void init() { + refreshAccessToken(); + } + + /** * 根据传入的统计请求数据,查询历史累计车流量数据。 * @@ -20,4 +63,451 @@ public class DcTrafficStatisticsServiceImpl implements IDcTrafficStatisticsServi // TODO return null; } + + /** + * 定时刷新访问令牌的函数。 + * 该方法使用Cron表达式定时执行,即每5小时执行一次。 + * 无参数和返回值。 + * 主要步骤包括: + * 1. 构建OkHttp客户端。 + * 2. 使用POST方法向指定URL发送请求,以获取新的访问令牌。 + * 3. 在请求成功时,解析响应体中的令牌信息并更新本地存储的令牌。 + */ + @Scheduled(cron = "0 0 */5 * * ?") + public void refreshAccessToken() { + OkHttp okHttp = new OkHttp(); + try { + // 构建请求并设置URL,携带appId和clientSecret进行身份验证 + okHttp.url(baseUrl + "/auth/client/token?appId=sdgs_it_hs_jihe&clientSecret=sdgs_it_hs_jihe") + .post(new Callback() { + // 请求失败时的回调处理,此处未实现具体逻辑 + @Override + public void onFailure(Call call, IOException e) {} + + // 请求成功时的回调处理 + @Override + public void onResponse(Call call, Response response) { + try { + // 判断响应体是否非空,非空则解析令牌信息 + if (response.body() != null) { + token = JSON.parseObject(response.body().string()); + } + } catch (IOException e) { + // 解析异常转为运行时异常抛出 + throw new RuntimeException(e); + } + } + }); + } catch (HttpException e) { + // 处理HTTP请求异常,转为运行时异常抛出 + throw new RuntimeException(e); + } + + } + + + /** + * 获取访问令牌。 + *

+ * 这个方法会尝试从存储的token中提取访问令牌。如果token存在,会组合token类型和访问令牌返回。 + * 如果token不存在,方法将返回null。 + * + * @return 如果存在有效的token,则返回构建的访问令牌字符串(包括token类型和访问令牌)。如果不存在有效的token,则返回null。 + */ + public String getAccessToken() { + // 检查token是否存在 + if (token != null) { + // 组合并返回token类型和访问令牌 + return token.getString("token_type") + " " + token.getString("access_token"); + } + // 如果token不存在,返回null + return null; + } + + /** + * 获取在途车辆流量(分车型) + */ + @Override + public JSONArray vehiclesInTransit() throws HttpException, IOException { + OkHttp okHttp = new OkHttp(); + + RequestParams requestParams = new RequestParams(); + + requestParams.put("sysid", sysid); + + Map headers = new HashMap<>(); + headers.put("Authorization", getAccessToken()); + + Response response // 请求响应 + = okHttp + .headers(headers) + .url(baseUrl + "/api/dc/query/rd_jihe_d_vehtypeonwayflow") // 请求地址 + .data(requestParams) // 请求参数 + .post(); // 请求方法 + + ResponseBody body = response.body(); + if (body != null) { + return JSON.parseArray(body.string()); + } + + return new JSONArray(); + } + + /** + * 在途车路段门架平均车速 + */ + @Override + public JSONArray currentAverageSpeed() throws IOException, HttpException { + + OkHttp okHttp = new OkHttp(); + + RequestParams requestParams = new RequestParams(); + + requestParams.put("sysid", sysid); + + Map headers = new HashMap<>(); + headers.put("Authorization", getAccessToken()); + + Response response // 请求响应 + = okHttp + .headers(headers) + .url(baseUrl + "/api/dc/query/rd_jihe_d_ganonwayavgspeed") // 请求地址 + .data(requestParams) // 请求参数 + .post(); // 请求方法 + + ResponseBody body = response.body(); + + JSONArray jsonArray = null; + + if (body != null) { + jsonArray = JSON.parseArray(body.string()); + } + + Map map = new HashMap<>(); + + if (jsonArray != null) { + jsonArray.forEach(jsonObject -> { + if (jsonObject instanceof JSONObject) { + String gantryId = ((JSONObject) jsonObject).getString("gantry_id"); + map.put(gantryId, ((JSONObject) jsonObject).getInteger("avg_speed")); + } + }); + } + + if (map.isEmpty()) { + return new JSONArray(); + } + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + queryWrapper.in(DcFacility::getFacilityCode, map.keySet()); + + List facilities = facilityService.list(queryWrapper); + + if (facilities == null || facilities.isEmpty()) { + return new JSONArray(); + } + + List roadSections = roadSectionService.selectDcRoadSectionListAll(null); + + JSONArray jsonArray1 = new JSONArray(); + + roadSections.forEach(item -> { + Integer startStakeMark = StakeMarkUtils.stakeMarkToInt(item.getStartStakeMark()); + Integer endStakeMark = StakeMarkUtils.stakeMarkToInt(item.getEndStakeMark()); + + for (DcFacility facility : facilities) { + Integer stakeMark = StakeMarkUtils.stakeMarkToInt(facility.getStakeMark()); + + if (stakeMark >= startStakeMark && stakeMark <= endStakeMark) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("sectionId", item.getId()); + jsonObject.put("sectionName", item.getSectionName()); + jsonObject.put("avgSpeed", map.get(facility.getFacilityCode())); + jsonObject.put("facilityCode", facility.getFacilityCode()); + jsonArray1.add(jsonObject); + break; + } + } + }); + + return jsonArray1; + } + + /** + * 获取当前拥堵事件信息 + */ + @Override + public JSONArray currentEventCongested() throws IOException, HttpException { + OkHttp okHttp = new OkHttp(); + + RequestParams requestParams = new RequestParams(); + + requestParams.put("sysid", sysid); + + Map headers = new HashMap<>(); + headers.put("Authorization", getAccessToken()); + + Response response // 请求响应 + = okHttp + .headers(headers) + .url(baseUrl + "/api/dc/query/rd_tr_congestion_jh") // 请求地址 + .data(requestParams) // 请求参数 + .post(); // 请求方法 + + ResponseBody body = response.body(); + if (body != null) { + return JSON.parseArray(body.string()); + } + + return new JSONArray(); + } + + /** + * 获取当前路段拥堵情况。 + * 该方法首先调用currentEventCongested()获取当前所有拥堵事件的信息,然后根据这些信息和道路路段的信息, + * 统计出每个路段的上行和下行的拥堵情况。 + * + * @return List 当前路段拥堵情况列表 + * @throws HttpException 抛出HttpException异常,当HTTP请求发生错误时。 + * @throws IOException 抛出IOException异常,当发生输入/输出错误时。 + */ + @Override + public List currentSectionCongested() throws HttpException, IOException { + + // 调用方法获取当前拥堵事件信息 + JSONArray currentEventCongested = currentEventCongested(); + + // 如果没有拥堵事件,则直接返回空列表 + if (currentEventCongested == null || currentEventCongested.isEmpty()) { + return new ArrayList<>(); + } + + // 初始化用于存储结果的列表 + List list = new ArrayList<>(); + + // 获取所有道路路段信息 + List dcRoadSections = dcRoadSectionService.selectDcRoadSectionListAll(null); + + // 遍历每个道路路段,分别计算上行和下行的拥堵情况 + dcRoadSections.forEach(dcRoadSection -> { + + // 初始化拥堵信息 + DcRoadSectionCongestion dcRoadSectionCongestion = new DcRoadSectionCongestion(); + + BeanUtil.copyProperties(dcRoadSection, dcRoadSectionCongestion); + dcRoadSectionCongestion.setUpCongestionSections(new ArrayList<>()); + dcRoadSectionCongestion.setDownCongestionSections(new ArrayList<>()); + + // 遍历当前拥堵事件,计算每个路段的拥堵情况 + for (Object object :currentEventCongested) { + if (object instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) object; + calculateSectionCongestion(jsonObject, dcRoadSectionCongestion); + } + } + + list.add(dcRoadSectionCongestion); + + }); + + return list; + } + + + /** + * 根据给定的JSON对象计算路段的拥堵情况。 + * + * @param jsonObject 包含拥堵信息的JSON对象,包括拥堵开始桩号、结束桩号和拥堵距离。 + * @param dcRoadSectionCongestion 包含路段基本信息和拥堵情况的对象,需要根据计算结果更新拥堵信息。 + */ + private void calculateSectionCongestion(JSONObject jsonObject, DcRoadSectionCongestion dcRoadSectionCongestion){ + + // 根据方向,计算对应方向的路段拥堵情况 + String dirCode = jsonObject.getString("dir_code"); + + List congestionSections; + + if (dirCode.equals("UP")) { + congestionSections = dcRoadSectionCongestion.getUpCongestionSections(); + } else { + congestionSections = dcRoadSectionCongestion.getDownCongestionSections(); + } + + // 拥堵开始桩号 + double startPileNo = jsonObject.getDouble("start_pile_no") * 1000; + // 拥堵结束桩号 + double endPileNo = jsonObject.getDouble("end_pile_no") * 1000; + + // 拥堵距离 + int jamDist = jsonObject.getInteger("jam_dist"); + + // 如果拥堵开始桩号大于拥堵结束桩号,则交换它们的值 + if (startPileNo > endPileNo) { + endPileNo = startPileNo - jamDist; + double tempStartPileNo = startPileNo; + startPileNo = endPileNo; + endPileNo = tempStartPileNo; + } else { + endPileNo = startPileNo + jamDist; + } + + // 路段开始桩号 + int startStakeMark = StakeMarkUtils.stakeMarkToInt(dcRoadSectionCongestion.getStartStakeMark()); + // 路段结束桩号 + int endStakeMark = StakeMarkUtils.stakeMarkToInt(dcRoadSectionCongestion.getEndStakeMark()); + + DcCongestionSection congestionSection = new DcCongestionSection(); + + // 拥堵状态 + int pubRunStatus = jsonObject.getInteger("pub_run_status"); + + // 拥堵状态 + congestionSection.setCongestionStatus(pubRunStatus); + + // -|-------startPileNo-----------------endPileNo------------|- + // 路段包含拥堵 + if (startStakeMark <= startPileNo && endPileNo <= endStakeMark) { + congestionSection.setCongestionStartStakeMark((int) startPileNo); + congestionSection.setCongestionEndStakeMark((int) endPileNo); + congestionSection.setCongestionDistance(jamDist); + congestionSections.add(congestionSection); + + if (pubRunStatus > dcRoadSectionCongestion.getCongestionStatus()) { + dcRoadSectionCongestion.setCongestionStatus(pubRunStatus); + } + return; + } + + // --startPileNo---|--------------------------|---endPileNo--- + // 拥堵包含路段 + if (startPileNo <= startStakeMark && endPileNo >= endStakeMark) { + congestionSection.setCongestionStartStakeMark(startStakeMark); + congestionSection.setCongestionEndStakeMark(endStakeMark); + congestionSection.setCongestionDistance(endStakeMark - startStakeMark); + congestionSections.add(congestionSection); + + if (pubRunStatus > dcRoadSectionCongestion.getCongestionStatus()) { + dcRoadSectionCongestion.setCongestionStatus(pubRunStatus); + } + return; + } + + // -|-----------------startPileNo-------------------|---endPileNo--- + // 路段包含开始拥堵桩号不包含结束拥堵桩号 + if (startPileNo >= startStakeMark && startPileNo <= endStakeMark && endPileNo >= endStakeMark) { + congestionSection.setCongestionStartStakeMark((int) startPileNo); + congestionSection.setCongestionEndStakeMark(endStakeMark); + congestionSection.setCongestionDistance((int) (endStakeMark - startPileNo)); + congestionSections.add(congestionSection); + + if (pubRunStatus > dcRoadSectionCongestion.getCongestionStatus()) { + dcRoadSectionCongestion.setCongestionStatus(pubRunStatus); + } + return; + } + + // ---startPileNo---|-----------------endPileNo-------------------|- + // 路段包含结束拥堵桩号不包含开始拥堵桩号 + if (endPileNo >= startStakeMark && endPileNo <= endStakeMark && startPileNo <= startStakeMark) { + congestionSection.setCongestionStartStakeMark(startStakeMark); + congestionSection.setCongestionEndStakeMark((int)endPileNo); + congestionSection.setCongestionDistance((endStakeMark - startStakeMark)); + congestionSections.add(congestionSection); + + if (pubRunStatus > dcRoadSectionCongestion.getCongestionStatus()) { + dcRoadSectionCongestion.setCongestionStatus(pubRunStatus); + } + } + + } + +/* private void calculateSectionCongestion(JSONObject jsonObject, DcRoadSectionCongestion dcRoadSectionCongestion){ + + // 根据方向,计算对应方向的路段拥堵情况 + String dirCode = jsonObject.getString("dir_code"); + + List congestionSections; + + if (dirCode.equals("UP")) { + congestionSections = dcRoadSectionCongestion.getUpCongestionSections(); + } else { + congestionSections = dcRoadSectionCongestion.getDownCongestionSections(); + } + + // 拥堵开始桩号 + double startPileNo = jsonObject.getDouble("start_pile_no") * 1000; + // 拥堵结束桩号 + double endPileNo = jsonObject.getDouble("end_pile_no") * 1000; + + // 拥堵距离 + int jamDist = jsonObject.getInteger("jam_dist"); + + // 路段开始桩号 + int startStakeMark = StakeMarkUtils.stakeMarkToInt(dcRoadSectionCongestion.getStartStakeMark()); + // 路段结束桩号 + int endStakeMark = StakeMarkUtils.stakeMarkToInt(dcRoadSectionCongestion.getEndStakeMark()); + + DcCongestionSection congestionSection = new DcCongestionSection(); + + // 拥堵状态 + int pubRunStatus = jsonObject.getInteger("pub_run_status"); + + // 拥堵状态 + congestionSection.setCongestionStatus(pubRunStatus); + + // 路段包含拥堵 + if (startStakeMark <= startPileNo && startPileNo <= endStakeMark) { + congestionSection.setCongestionStartStakeMark((int) startPileNo); + congestionSection.setCongestionEndStakeMark((int) endPileNo); + congestionSection.setCongestionDistance(jamDist); + congestionSections.add(congestionSection); + + if (pubRunStatus > dcRoadSectionCongestion.getCongestionStatus()) { + dcRoadSectionCongestion.setCongestionStatus(pubRunStatus); + } + + } + + }*/ + + /** + * 获取车道占有率信息 + */ + @Override + public JSONArray laneOccupancy(String startDate, String endDate) throws HttpException, IOException { + OkHttp okHttp = new OkHttp(10); + + RequestParams requestParams = new RequestParams(); + + requestParams.put("sysid", sysid); + + JSONObject parameters = new JSONObject() { + { + put("start_date", startDate); + put("end_date", endDate); + } + }; + + requestParams.put("parameters", parameters.toJSONString()); + + Map headers = new HashMap<>(); + headers.put("Authorization", getAccessToken()); + + Response response // 请求响应 + = okHttp + .headers(headers) + .url(baseUrl + "/api/dc/query/rd_jihe_d_gantryoccupationbyhour") // 请求地址 + .data(requestParams) // 请求参数 + .post(); // 请求方法 + + ResponseBody body = response.body(); + if (body != null) { + return JSON.parseArray(body.string()); + } + + return new JSONArray(); + } + + }