LsStationRouteServiceImpl.java 13.3 KB
package com.bsth.service.impl;

import com.bsth.annotation.BusinessDescription;
import com.bsth.entity.*;
import com.bsth.entity.search.CustomerSpecs;
import com.bsth.repository.*;
import com.bsth.service.LsStationRouteService;
import com.bsth.util.CoordinateConverter;
import com.bsth.util.CustomBeanUtils;
import com.bsth.util.GeoConverter;
import org.geolatte.geom.LineString;
import org.geolatte.geom.Point;
import org.geolatte.geom.Polygon;
import org.geolatte.geom.codec.Wkt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Hill
 */
@Service
public class LsStationRouteServiceImpl extends BaseServiceImpl<LsStationRoute, Integer> implements LsStationRouteService {

    @Autowired
    private LsStationRouteRepository lsStationRouteRepository;

    @Autowired
    private StationRouteRepository stationRouteRepository;

    @Autowired
    private StationRepository stationRepository;

    @Autowired
    private LsSectionRouteRepository lsSectionRouteRepository;

    @Autowired
    private SectionRouteRepository sectionRouteRepository;

    @Autowired
    private SectionRepository sectionRepository;

    @Autowired
    private LineRepository lineRepository;

    @Autowired
    private LineVersionsRepository lineVersionsRepository;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public Iterable<LsStationRoute> findAllByParams(Map<String, Object> map) {
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.ASC, "directions"));
        orders.add(new Sort.Order(Sort.Direction.ASC, "stationRouteCode"));

        return lsStationRouteRepository.findAll(new CustomerSpecs<>(map), Sort.by(orders));
    }

    /**
     * 获取当前站点以及下一站点路由
     * @param id
     * @return
     */
    @Override
    public List<LsStationRoute> findCurrentAndNext(Integer id) {
        if (id == null) {
            throw new IllegalArgumentException("需正确传入站点路由ID参数");
        }
        List<LsStationRoute> stationRoutes = new ArrayList<>();
        LsStationRoute stationRoute = lsStationRouteRepository.findById(id).get();
        Map<String, Object> params = new HashMap<>();
        params.put("line.id_eq", stationRoute.getLine().getId());
        params.put("versions_eq", stationRoute.getVersions());
        params.put("directions_eq", stationRoute.getDirections());
        params.put("destroy_eq", 0);
        params.put("stationRouteCode_gt", stationRoute.getStationRouteCode());
        List<LsStationRoute> stationRoutes1 = lsStationRouteRepository.findAll(new CustomerSpecs<>(params), Sort.by(Sort.Order.asc("stationRouteCode")));
        stationRoutes.add(stationRoute);
        if (stationRoutes1.size() > 0) {
            stationRoutes.add(stationRoutes1.get(0));
        }

        return stationRoutes;
    }

    /**
     * 批量撤销站点路由
     * @param ids
     */
    @BusinessDescription(value = "批量撤销站点路由")
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void batchDestroy(List<Integer> ids) {
        if (ids.size() > 0) {
            Integer id = ids.get(0);
            LsStationRoute stationRoute = lsStationRouteRepository.findById(id).get();
            Integer lineId = stationRoute.getLine().getId();
            Integer currentVersion = lineVersionsRepository.findCurrentVersion(lineId);
            if (stationRoute.getVersions() < currentVersion) {
                throw new IllegalArgumentException("历史版本不可变更");
            }

            lsStationRouteRepository.batchDestroy(ids);
            remark(stationRoute);
            if (stationRoute.getVersions().equals(currentVersion)) {
                refreshCurrent(lineId, currentVersion);
            }
        }
    }

    @Transactional
    @Override
    public Map<String, Object> addRoutes(Integer lineId, Integer versions, Integer directions, List<LsStationRoute> stationRoutes, List<LsSectionRoute> sectionRoutes) {
        Map<String, Object> result = new HashMap<>();
        Line line = lineRepository.findById(lineId).get();
        Integer version = lineVersionsRepository.findCurrentVersion(lineId);
        if (line == null) {
            throw new RuntimeException(String.format("未找到ID为%d的线路信息", lineId));
        }
        stationRoutesHandle(line, versions, directions, stationRoutes);
        List<Section> sections = sectionRoutesHandle(line, versions, directions, sectionRoutes);

        //stationRepository.saveAll(stations);
        sectionRepository.saveAll(sections);
        lsStationRouteRepository.saveAll(stationRoutes);
        lsSectionRouteRepository.saveAll(sectionRoutes);
        if (versions.equals(version)) {
            refreshCurrent(lineId, version);
        }

        return result;
    }

    private void stationRoutesHandle(Line line, Integer versions, Integer directions, List<LsStationRoute> stationRoutes) {
        int count = 0;
        for (int len = stationRoutes.size();count < len;) {
            LsStationRoute stationRoute = stationRoutes.get(count);
            stationRoute.setStationMark(count == 0 ? "B" : count == len - 1 ? "E" : "Z");
            count++;
            stationRoute.setLine(line);
            stationRoute.setVersions(versions);
            stationRoute.setDirections(directions);
            stationRoute.setLineCode(line.getLineCode());
            stationRoute.setStationRouteCode(100 * count);
            stationRoute.setStationCode(stationRoute.getStation().getStationCode());
        }
    }

    private List<Section> sectionRoutesHandle(Line line, Integer versions, Integer directions, List<LsSectionRoute> sectionRoutes) {
        List<Section> sections = new ArrayList<>();
        int currentId = sectionRepository.findLatestSectionId(), count = 0;
        for (int len = sectionRoutes.size();count < len;) {
            LsSectionRoute sectionRoute = sectionRoutes.get(count++);
            sectionRoute.setLine(line);
            sectionRoute.setVersions(versions);
            sectionRoute.setDirections(directions);
            sectionRoute.setLineCode(line.getLineCode());
            sectionRoute.setSectionrouteCode(100 * count);
            String wkt = sectionRoute.getSection().getBsectionVectorWkt();
            Section section = sectionRoute.getSection();
            section.setBsectionVector((LineString) Wkt.fromWkt(wkt));
            section.setGsectionVector(GeoConverter.lineStringBd2wgs(wkt));
            section.setId(currentId + count);
            section.setSectionCode(section.getId().toString());
            sectionRoute.setSectionCode(section.getSectionCode());
            sections.add(section);
        }

        return sections;
    }

    @BusinessDescription(value = "添加站点路由")
    @Transactional
    @Override
    public Map<String, Object> add(LsStationRoute stationRoute) {
        Station station = stationRoute.getStation();
        Line line = lineRepository.findById(stationRoute.getLine().getId()).get();
        Integer currentVersion = lineVersionsRepository.findCurrentVersion(line.getId());
        boolean isPresent = stationRepository.findById(station.getId()).isPresent();
        stationRoute.setLineCode(line.getLineCode());
        if (stationRoute.getVersions() < currentVersion) {
            throw new IllegalArgumentException("历史版本不可变更");
        }

        // 中心点坐标信息
        if (!isPresent) {
            centerPoint(station);
        }

        // 多边形缓冲区
        if ("d".equals(stationRoute.getShapedType())) {
            bufferPolygon(stationRoute);
        }

        lsStationRouteRepository.updateStatiouRouteCode(stationRoute);
        if (!isPresent) {
            stationRepository.save(station);
        }
        lsStationRouteRepository.save(stationRoute);
        remark(stationRoute);
        if (stationRoute.getVersions().equals(currentVersion)) {
            refreshCurrent(line.getId(), currentVersion);
        }

        return new HashMap<>();
    }

    @Transactional
    @Override
    public Map<String, Object> modify(LsStationRoute stationRoute) {
        LsStationRoute stationRoute1 = lsStationRouteRepository.findById(stationRoute.getId()).get();
        Integer currentVersion = lineVersionsRepository.findCurrentVersion(stationRoute1.getLine().getId());
        if (stationRoute1.getVersions() < currentVersion) {
            throw new IllegalArgumentException("历史版本不可变更");
        }

        // 多边形缓冲区
        if ("d".equals(stationRoute.getShapedType())) {
            bufferPolygon(stationRoute);
        }

        lsStationRouteRepository.updateStatiouRouteCode(stationRoute);
        CustomBeanUtils.copyPropertiesIgnoredNull(stationRoute, stationRoute1);
        lsStationRouteRepository.save(stationRoute1);
        remark(stationRoute1);
        if (stationRoute.getVersions().equals(currentVersion)) {
            refreshCurrent(stationRoute1.getLine().getId(), currentVersion);
        }

        return new HashMap<>();
    }

    @Transactional
    @Override
    public Map<String, Object> exchangeDirection(int lineId, int version) {
        lsStationRouteRepository.exchangeDirection(lineId, version);
        lsSectionRouteRepository.exchangeDirection(lineId, version);

        return new HashMap<>();
    }

    @Transactional
    @Override
    public Map<String, Object> modifyDistance(List<Integer> ids, List<Double> distances) {
        LsStationRoute stationRoute = lsStationRouteRepository.findById(ids.get(0)).get();
        int currentVersion = lineVersionsRepository.findCurrentVersion(stationRoute.getLine().getId());
        if (stationRoute.getVersions() < currentVersion) {
            throw new IllegalArgumentException("历史版本不可变更");
        }

        jdbcTemplate.batchUpdate("UPDATE bsth_c_ls_stationroute SET distances = ? WHERE id = ?", new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                ps.setDouble(1, distances.get(i));
                ps.setInt(2, ids.get(i));
            }

            @Override
            public int getBatchSize() {
                return ids.size();
            }
        });

        if (stationRoute.getVersions() == currentVersion) {
            refreshCurrent(stationRoute.getLine().getId(), currentVersion);
        }

        return new HashMap<>();
    }

    @Transactional
    @Override
    public Map<String, Object> circularRouteHandle(Integer lineId, Integer version) {
        Line line = lineRepository.findById(lineId).get();
        Integer currentVersion = lineVersionsRepository.findCurrentVersion(lineId);
        if (version < currentVersion) {
            throw new IllegalArgumentException("历史版本不可变更");
        }

        Map<String, Object> params = new HashMap<>();
        params.put("line.id_eq", lineId);
        params.put("versions_eq", version);
        params.put("destroy_eq", 0);
        params.put("stationMark_in", "B,E");

        Sort sort = Sort.by(Sort.Order.asc("directions"), Sort.Order.asc("stationRouteCode"));
        List<LsStationRoute> routes = lsStationRouteRepository.findAll(new CustomerSpecs<>(params), sort);
        LsStationRoute route = routes.get(0);
        for (int i = 1;i < routes.size();i++) {
            LsStationRoute route1 = routes.get(i);
            if (line.getLinePlayType() == 1 && route1.getDirections() == 1) {
                break;
            }
            route1.setStationCode(route.getStationCode());
            route1.setStation(route.getStation());
        }
        lsStationRouteRepository.saveAll(routes);
        if (version.equals(currentVersion)) {
            refreshCurrent(lineId, version);
        }

        return new HashMap<>();
    }

    protected void centerPoint(Station station) {
        // 中心点坐标信息
        String wkt = station.getCenterPointWkt();
        if (!StringUtils.isEmpty(wkt)) {
            org.geolatte.geom.Point baidu = (org.geolatte.geom.Point) Wkt.fromWkt(wkt);
            org.geolatte.geom.Point wgs = GeoConverter.pointBd2wgs(wkt);
            station.setCenterPoint(baidu);
            station.setCenterPointWgs(wgs);
        }
    }

    protected void bufferPolygon(LsStationRoute stationRoute) {
        String wkt = stationRoute.getBufferPolygonWkt();
        if (!StringUtils.isEmpty(wkt)) {
            stationRoute.setBufferPolygon((Polygon) Wkt.fromWkt(wkt));
            stationRoute.setBufferPolygonWgs(GeoConverter.polygonBd2wgs(wkt));
        }
    }

    protected void remark(LsStationRoute stationRoute) {
        lsStationRouteRepository.updateStartZ(stationRoute);
        lsStationRouteRepository.updateStartB(stationRoute);
        lsStationRouteRepository.updateStartE(stationRoute);
    }

    protected void refreshCurrent(int lineId, int version) {
        stationRouteRepository.deleteByLineAndVersion(lineId, version);
        stationRouteRepository.updateFromHistory(lineId, version);
    }
}