| | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.zy.acs.common.utils.CodeUtils; |
| | | import com.zy.acs.framework.common.Cools; |
| | | import com.zy.acs.manager.common.domain.CodeExcel; |
| | | import com.zy.acs.manager.common.exception.BusinessException; |
| | | import com.zy.acs.manager.manager.entity.Code; |
| | |
| | | import com.zy.acs.manager.manager.service.CodeGapService; |
| | | import com.zy.acs.manager.manager.service.CodeService; |
| | | import com.zy.acs.manager.manager.service.RouteService; |
| | | import com.zy.acs.framework.common.Cools; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import javax.annotation.PostConstruct; |
| | | import java.util.*; |
| | | |
| | | @Slf4j |
| | | @Service("codeService") |
| | | public class CodeServiceImpl extends ServiceImpl<CodeMapper, Code> implements CodeService { |
| | | |
| | |
| | | @Autowired |
| | | private RouteService routeService; |
| | | |
| | | private static final double STRAIGHT_LINE_SIN_THRESHOLD = 1e-3; |
| | | |
| | | public static final Map<Long, Code> CODE_ID_CACHE = new HashMap<>(); |
| | | public static final Map<String, Code> CODE_DATA_CACHE = new HashMap<>(); |
| | | |
| | | @PostConstruct |
| | | public void init() { |
| | | for (Code code : this.list()) { |
| | | CODE_ID_CACHE.put(code.getId(), code); |
| | | CODE_DATA_CACHE.put(code.getData(), code); |
| | | } |
| | | log.info("The code cache was initialized..."); |
| | | } |
| | | |
| | | @Override |
| | | public Code selectByData(String data) { |
| | | return this.getOne(new LambdaQueryWrapper<Code>().eq(Code::getData, data)); |
| | | } |
| | | |
| | | @Override |
| | | public Code getCacheById(Long id) { |
| | | Code code = CODE_ID_CACHE.get(id); |
| | | if (code == null) { |
| | | code = this.getById(id); |
| | | if (code != null) { |
| | | CODE_ID_CACHE.put(id, code); |
| | | } |
| | | } |
| | | return code; |
| | | } |
| | | |
| | | @Override |
| | | public Code getCacheByData(String data) { |
| | | Code code = CODE_DATA_CACHE.get(data); |
| | | if (code == null) { |
| | | code = this.selectByData(data); |
| | | if (null != code) { |
| | | CODE_DATA_CACHE.put(data, code); |
| | | } |
| | | } |
| | | return code; |
| | | } |
| | | |
| | | @Override |
| | | public void refreshCornerByCodeIds(List<Long> codeIds) { |
| | | if (Cools.isEmpty(codeIds)) { |
| | | return; |
| | | } |
| | | Date now = new Date(); |
| | | Set<Long> targets = new HashSet<>(codeIds); |
| | | for (Long codeId : targets) { |
| | | Code code = this.getCacheById(codeId); |
| | | if (null == code) { |
| | | continue; |
| | | } |
| | | boolean corner = shouldMarkAsCorner(code, routeService.getAdjacencyNode(codeId)); |
| | | Integer cornerVal = corner ? 1 : 0; |
| | | if (!Objects.equals(code.getCorner(), cornerVal)) { |
| | | code.setCorner(cornerVal); |
| | | code.setUpdateTime(now); |
| | | if (!this.updateById(code)) { |
| | | throw new BusinessException(code.getData() + "拐角标记更新失败"); |
| | | } |
| | | CODE_ID_CACHE.put(code.getId(), code); |
| | | CODE_DATA_CACHE.put(code.getData(), code); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private boolean shouldMarkAsCorner(Code code, List<Long> adjacencyIds) { |
| | | if (Cools.isEmpty(adjacencyIds)) { |
| | | return false; |
| | | } |
| | | if (adjacencyIds.size() > 2) { |
| | | return true; |
| | | } |
| | | if (adjacencyIds.size() < 2) { |
| | | return false; |
| | | } |
| | | Code first = this.getCacheById(adjacencyIds.get(0)); |
| | | Code second = this.getCacheById(adjacencyIds.get(1)); |
| | | if (null == first || null == second) { |
| | | return false; |
| | | } |
| | | return !isStraightLine(code, first, second); |
| | | } |
| | | |
| | | private boolean isStraightLine(Code center, Code first, Code second) { |
| | | if (center.getX() == null || center.getY() == null |
| | | || first.getX() == null || first.getY() == null |
| | | || second.getX() == null || second.getY() == null) { |
| | | return true; |
| | | } |
| | | double v1x = first.getX() - center.getX(); |
| | | double v1y = first.getY() - center.getY(); |
| | | double v2x = second.getX() - center.getX(); |
| | | double v2y = second.getY() - center.getY(); |
| | | double len1 = Math.hypot(v1x, v1y); |
| | | double len2 = Math.hypot(v2x, v2y); |
| | | if (len1 == 0 || len2 == 0) { |
| | | return true; |
| | | } |
| | | double sinValue = Math.abs(v1x * v2y - v1y * v2x) / (len1 * len2); |
| | | return sinValue < STRAIGHT_LINE_SIN_THRESHOLD; |
| | | } |
| | | |
| | | @Override |
| | |
| | | Double maxY = Double.parseDouble(String.valueOf(map.get("max_y"))); |
| | | |
| | | // 缩放后需要的偏移量 |
| | | double scaleOffsetX = width * (1 -CodeUtils.ADAPTATION_SCALE) / 2; |
| | | double scaleOffsetY = height * (1 -CodeUtils.ADAPTATION_SCALE) / 2; |
| | | double scaleOffsetX = width * (1 - CodeUtils.ADAPTATION_SCALE) / 2; |
| | | double scaleOffsetY = height * (1 - CodeUtils.ADAPTATION_SCALE) / 2; |
| | | |
| | | List<Code> codeList = this.list(); |
| | | for (Code code : codeList) { |
| | |
| | | return this.baseMapper.selectDistinctCountFromY(); |
| | | } |
| | | |
| | | @Override |
| | | public List<Code> getAllLocCode() { |
| | | List<Long> ids = this.baseMapper.selectAllLocCode(); |
| | | List<Code> codeList = new ArrayList<>(); |
| | | for (Long id : ids) { |
| | | Code byId = this.getById(id); |
| | | if (byId != null) { |
| | | codeList.add(byId); |
| | | } |
| | | |
| | | } |
| | | return codeList; |
| | | } |
| | | |
| | | } |