| | |
| | | if (holidayLabel == null) { |
| | | throw new IllegalArgumentException("不支持的节假日类型"); |
| | | } |
| | | List<HolidayCalendar> holidayDays = configService.findHolidayDays(year, holidayType); |
| | | if (holidayDays.isEmpty()) { |
| | | throw new IllegalArgumentException("所选年份和节假日尚未配置日期,请先在系统配置中维护节假日"); |
| | | } |
| | | List<String> dayLabels = dayLabels(holidayDays); |
| | | int dayCount = holidayDays.size(); |
| | | List<Integer> years = Arrays.asList(year, year - 1, year - 2); |
| | | Map<Integer, YearData> yearData = new LinkedHashMap<>(); |
| | | for (Integer item : years) { |
| | | yearData.put(item, buildYearData(item, holidayType, dayCount)); |
| | | yearData.put(item, buildYearData(item, holidayType)); |
| | | } |
| | | YearData selected = yearData.get(year); |
| | | if (selected == null || !selected.hasAnyData()) { |
| | |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | prefix + "全省跨区域人员流动量情况", |
| | | chartService.lineChart("万人次", |
| | | series(years, yearData, item -> item.totalDaily), false, dayLabels, 2, 1100, 715), |
| | | series(years, yearData, item -> item.totalDaily), false, 1100, 715), |
| | | lineImageSize(5268595L, 3424555L))); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期累计跨区域人员流动量走势", |
| | | chartService.lineChart("万人次", |
| | | series(years, yearData, item -> item.totalCumulative), false, dayLabels, 2, 1100, 590), |
| | | series(years, yearData, item -> item.totalCumulative), false, 1100, 590), |
| | | lineImageSize(5268595L, 2821305L))); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期各交通运输方式客运量占比情况", |
| | |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期自驾出行量情况", |
| | | chartService.lineChart("万人次", |
| | | series(years, yearData, item -> item.selfDrivingPersonFlow), false, dayLabels, 2, 1100, 522), |
| | | series(years, yearData, item -> item.selfDrivingPersonFlow), false, 1100, 522), |
| | | lineImageSize(5232400L, 2484120L))); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期铁路客运量情况", |
| | | chartService.lineChart("万人次", |
| | | series(years, yearData, item -> item.rail), false, dayLabels, 2, 1100, 445), |
| | | series(years, yearData, item -> item.rail), false, 1100, 445), |
| | | lineImageSize(5264785L, 2129155L))); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期水路客运量情况", |
| | | chartService.lineChart("万人次", |
| | | series(years, yearData, item -> item.water), false, dayLabels, 2, 1100, 433), |
| | | series(years, yearData, item -> item.water), false, 1100, 433), |
| | | lineImageSize(5274310L, 2075815L))); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期民航客运量情况", |
| | | chartService.lineChart("万人次", |
| | | series(years, yearData, item -> item.civilAviation), false, dayLabels, 2, 1100, 521), |
| | | series(years, yearData, item -> item.civilAviation), false, 1100, 521), |
| | | lineImageSize(5271135L, 2496185L))); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期道路客运量情况", |
| | | chartService.lineChart("万人次", |
| | | series(years, yearData, item -> item.road), false, dayLabels, 2, 1100, 590), |
| | | series(years, yearData, item -> item.road), false, 1100, 590), |
| | | lineImageSize(5268595L, 2821305L))); |
| | | |
| | | blocks.add(new HolidayTrendWordService.SectionBlock("三、车流量走势")); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期高速公路车流量情况", |
| | | chartService.lineChart("万辆次", |
| | | series(years, yearData, item -> item.expressway), false, dayLabels, 2, 1100, 590), |
| | | series(years, yearData, item -> item.expressway), false, 1100, 590), |
| | | lineImageSize(5268595L, 2821305L))); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期普通国省道车流量情况", |
| | | chartService.lineChart("万辆次", |
| | | series(years, yearData, item -> item.nationalProvincial), false, dayLabels, 2, 1100, 590), |
| | | series(years, yearData, item -> item.nationalProvincial), false, 1100, 590), |
| | | lineImageSize(5268595L, 2821305L))); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期全省车流总量情况", |
| | | chartService.lineChart("万辆次", |
| | | series(years, yearData, item -> item.totalVehicleFlow), false, dayLabels, 2, 1100, 590), |
| | | series(years, yearData, item -> item.totalVehicleFlow), false, 1100, 590), |
| | | lineImageSize(5268595L, 2821305L))); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期公路出行结构", |
| | |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | "“" + holidayLabel + "”假期每日客流构成变化", |
| | | chartService.stackedBarChart("占比", |
| | | dayLabels, |
| | | dailyShareSeries(selected, dayCount), true, 1000, 607), true, |
| | | HolidayTrendChartService.DAY_LABELS, |
| | | dailyShareSeries(selected), true, 1000, 607), true, |
| | | new HolidayTrendWordService.ImageSize(5106670L, 3097530L))); |
| | | |
| | | blocks.add(new HolidayTrendWordService.SectionBlock("附录二 普通国省道观测站路网运行")); |
| | | ObservationData observation = observationData(holidayDays); |
| | | ObservationData observation = observationData(year, holidayType); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | prefix + "普通国省道观测站平均机动车速度", |
| | | chartService.lineChart("公里/小时", |
| | | Collections.singletonList(series("平均速度", observation.speed)), false, dayLabels, 2, 1100, 590), |
| | | Collections.singletonList(series("平均速度", observation.speed)), false, 1100, 590), |
| | | lineImageSize(5268595L, 2821305L))); |
| | | blocks.add(new HolidayTrendWordService.ChartBlock( |
| | | prefix + "普通国省道观测站平均拥挤度", |
| | | chartService.lineChart("拥挤度", |
| | | Collections.singletonList(series("平均拥挤度", observation.congestion)), false, dayLabels, 2, 1100, 590), |
| | | Collections.singletonList(series("平均拥挤度", observation.congestion)), false, 1100, 590), |
| | | lineImageSize(5268595L, 2821305L))); |
| | | |
| | | File template = resolveTemplateFile(); |
| | |
| | | } |
| | | } |
| | | |
| | | private YearData buildYearData(int year, String holidayType, int dayCount) { |
| | | private YearData buildYearData(int year, String holidayType) { |
| | | List<DailyMetrics> metrics = new ArrayList<>(); |
| | | for (int day = 1; day <= dayCount; day++) { |
| | | for (int day = 1; day <= HolidayTrendChartService.DAY_LABELS.size(); day++) { |
| | | metrics.add(statService.dailyMetrics(year, holidayType, day)); |
| | | } |
| | | YearData data = new YearData(); |
| | |
| | | return result; |
| | | } |
| | | |
| | | private List<HolidayTrendChartService.ChartSeries> dailyShareSeries(YearData data, int dayCount) { |
| | | private List<HolidayTrendChartService.ChartSeries> dailyShareSeries(YearData data) { |
| | | List<HolidayTrendChartService.ChartSeries> result = new ArrayList<>(); |
| | | result.add(series("自驾", share(data.selfDrivingPersonFlow, data, dayCount))); |
| | | result.add(series("道路", share(data.road, data, dayCount))); |
| | | result.add(series("铁路", share(data.rail, data, dayCount))); |
| | | result.add(series("民航", share(data.civilAviation, data, dayCount))); |
| | | result.add(series("水路", share(data.water, data, dayCount))); |
| | | result.add(series("自驾", share(data.selfDrivingPersonFlow, data))); |
| | | result.add(series("道路", share(data.road, data))); |
| | | result.add(series("铁路", share(data.rail, data))); |
| | | result.add(series("民航", share(data.civilAviation, data))); |
| | | result.add(series("水路", share(data.water, data))); |
| | | return result; |
| | | } |
| | | |
| | | private List<BigDecimal> share(List<BigDecimal> values, YearData data, int dayCount) { |
| | | private List<BigDecimal> share(List<BigDecimal> values, YearData data) { |
| | | List<BigDecimal> result = new ArrayList<>(); |
| | | for (int i = 0; i < dayCount; i++) { |
| | | for (int i = 0; i < HolidayTrendChartService.DAY_LABELS.size(); i++) { |
| | | BigDecimal total = dayTotal(data, i); |
| | | BigDecimal value = valueAt(values, i); |
| | | result.add(total == null || total.signum() == 0 |
| | |
| | | series("道路客运量", road)); |
| | | } |
| | | |
| | | private ObservationData observationData(List<HolidayCalendar> days) { |
| | | private ObservationData observationData(int year, String holidayType) { |
| | | List<HolidayCalendar> days = configService.findHolidayDays(year, holidayType); |
| | | if (days.isEmpty()) { |
| | | return new ObservationData(nulls(0), nulls(0)); |
| | | return new ObservationData(nulls(), nulls()); |
| | | } |
| | | LocalDate start = days.get(0).getHolidayDate(); |
| | | LocalDate end = days.get(days.size() - 1).getHolidayDate(); |
| | | LocalDate end = start.plusDays(HolidayTrendChartService.DAY_LABELS.size() - 1L); |
| | | List<ObservationDailyOperation> rows = observationStationFlowMapper.selectDailyOperations(start, end); |
| | | Map<LocalDate, ObservationDailyOperation> byDate = new LinkedHashMap<>(); |
| | | for (ObservationDailyOperation row : rows) { |
| | |
| | | } |
| | | List<BigDecimal> speed = new ArrayList<>(); |
| | | List<BigDecimal> congestion = new ArrayList<>(); |
| | | for (HolidayCalendar day : days) { |
| | | ObservationDailyOperation row = byDate.get(day.getHolidayDate()); |
| | | for (int i = 0; i < HolidayTrendChartService.DAY_LABELS.size(); i++) { |
| | | ObservationDailyOperation row = byDate.get(start.plusDays(i)); |
| | | speed.add(row == null ? null : row.getAverageSpeed()); |
| | | congestion.add(row == null ? null : row.getAverageCongestion()); |
| | | } |
| | |
| | | |
| | | private List<BigDecimal> percentageChanges(List<BigDecimal> current, List<BigDecimal> previous) { |
| | | List<BigDecimal> result = new ArrayList<>(); |
| | | int size = Math.max(current == null ? 0 : current.size(), previous == null ? 0 : previous.size()); |
| | | for (int i = 0; i < size; i++) { |
| | | for (int i = 0; i < HolidayTrendChartService.DAY_LABELS.size(); i++) { |
| | | BigDecimal currentValue = valueAt(current, i); |
| | | BigDecimal previousValue = valueAt(previous, i); |
| | | BigDecimal ratio = HolidayNumberUtils.divide(currentValue, previousValue); |
| | |
| | | } |
| | | |
| | | private List<BigDecimal> nulls() { |
| | | return nulls(HolidayTrendChartService.DAY_LABELS.size()); |
| | | } |
| | | |
| | | private List<BigDecimal> nulls(int size) { |
| | | List<BigDecimal> result = new ArrayList<>(); |
| | | for (int i = 0; i < size; i++) result.add(null); |
| | | for (int i = 0; i < HolidayTrendChartService.DAY_LABELS.size(); i++) result.add(null); |
| | | return result; |
| | | } |
| | | |
| | | static List<String> dayLabels(List<HolidayCalendar> days) { |
| | | List<String> labels = new ArrayList<>(); |
| | | if (days == null) return labels; |
| | | for (HolidayCalendar day : days) { |
| | | if (day == null || day.getHolidayDate() == null) continue; |
| | | labels.add(day.getHolidayDate().getMonthValue() + "月" |
| | | + day.getHolidayDate().getDayOfMonth() + "日"); |
| | | } |
| | | return labels; |
| | | } |
| | | |
| | | private HolidayTrendWordService.ImageSize lineImageSize(long width, long height) { |