package com.its.vms.service; import com.its.app.utils.FloodFill; import com.its.app.utils.ItsUtils; import com.its.vms.config.ApplicationConfig; import com.its.vms.dao.mapper.VmsSymbMapper; import com.its.vms.dto.TbVmsSymbIfscDto; import com.its.vms.dto.TbVmsSymbLibDto; import com.its.vms.entity.TbVmsSymbIfsc; import com.its.vms.entity.TbVmsSymbLib; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Slf4j @Service @RequiredArgsConstructor public class VmsSymbService { private final ApplicationConfig config; private final VmsSymbMapper vmsSymbMapper; private final ConcurrentHashMap symbMap = new ConcurrentHashMap<>(); public TbVmsSymbLibDto find(String symbLibNmbr) { return this.symbMap.get(symbLibNmbr); } public void loadVmsSymbInfo() { loadVmsSymbLib(); loadVmsSymbCellInfo(); } public void loadVmsSymbLib() { try { List infoList = this.vmsSymbMapper.selectVmsSymbLib(); log.info("VmsSymbService.loadVmsSymbLib: {} EA", infoList.size()); infoList.forEach(data -> { // 심벌 유형(SBT0:일반심벌이미지,SBT1:소통정보배경,SBT2:소통정보이미지,SBT3:동영상,SBT4:대기환경등급) // 소통정보이미지 때문에 이미지번호에 "0" 을 추가하여 이미지번호로 사용함 String updtDt = ""; TbVmsSymbLibDto obj = data.toDto(); TbVmsSymbLibDto oldObj = this.symbMap.get(obj.getSymbLibNmbr()); if (oldObj != null) { updtDt = oldObj.getUpdtDt(); } this.symbMap.put(obj.getSymbLibNmbr(), obj); if ("SBT4".equals(obj.getSymbType())) { // 대기환경등급 String symbExpl = data.getSymbExpl(); if (symbExpl != null) { String[] symbNmbrArr = symbExpl.split("\\^"); for (String symbNmbr : symbNmbrArr) { obj.getGradSymbLibNmbrList().add(symbNmbr + "0"); } } } obj.setLocalFileName(this.config.getFtpImageDir() + obj.getSymbFileNm()); obj.setFtpFileName(ApplicationConfig.FTP_IMAGE + File.separator + obj.getSymbFileNm()); // Ftp 다운로드 명을 설정 // 심벌 유형(SBT0:일반심벌이미지,SBT1:소통정보배경,SBT2:소통정보이미지,SBT3:동영상) if ("SBT3".equals(obj.getSymbType())) { //위에서 이미지저장하기 위해 파일명을 변경하기 때문에 여기서 동영상 파일명을 다시 읽어온다 obj.setSymbFileNm(data.getSymbFileNm()); //동영상인 경우 동영상 파일명 obj.setLocalFileName(this.config.getFtpVideoDir() + obj.getSymbFileNm()); obj.setFtpFileName(ApplicationConfig.FTP_VIDEO + File.separator + obj.getSymbFileNm()); // Ftp 다운로드 명을 설정 } if ("SBT2".equals(obj.getSymbType())) { //심벌 유형(SBT0:일반심벌이미지,SBT1:소통정보배경,SBT2:소통정보이미지,SBT3:동영상) //소통정보 등급에 따른 이미지를 새롭게 추가한다. for (int nTrf = 1; nTrf <= 3; nTrf++) { String trfUpdtDt = ""; String trafSymbLibNmbr = data.getSymbLibNmbr() + String.valueOf(nTrf); TbVmsSymbLibDto trfObj = this.symbMap.get(trafSymbLibNmbr); if (trfObj != null) { trfUpdtDt = trfObj.getUpdtDt(); } trfObj = obj.clone(trafSymbLibNmbr); this.symbMap.put(trfObj.getSymbLibNmbr(), trfObj); Image imgBmp = obj.getImage(); // 원천이미지를 가지고 온다. if (imgBmp == null) { log.error("VmsSymbService.loadVmsSymbLib: Image Data Error: {}", trafSymbLibNmbr); continue; } String imagFmt = "bmp"; BufferedImage formImage = new BufferedImage(imgBmp.getWidth(null), imgBmp.getHeight(null), ("png".equals(imagFmt) ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB)); Graphics2D g2d = formImage.createGraphics(); FloodFill floodFill = new FloodFill(imgBmp); floodFill.setAntialiased(false); int orgColor = floodFill.getImage().getRGB(obj.getPosX(), obj.getPosY()); int trfColor = VmsSymbService.getGradColor(nTrf); if (orgColor != trfColor) { floodFill.fill(obj.getPosX(), obj.getPosY(), VmsSymbService.getTrafColor(nTrf)); } g2d.drawImage(floodFill.getImage(), 0, 0, imgBmp.getWidth(null), imgBmp.getHeight(null), null); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { ImageIO.write(formImage, imagFmt, out); } catch (IOException e) { log.error("VmsSymbService.loadVmsSymbLib: Image Convert error: {}", trafSymbLibNmbr); } g2d.dispose(); trfObj.setImagData(out.toByteArray()); trfObj.setLocalFileName(this.config.getFtpImageDir() + trfObj.getSymbFileNm()); trfObj.setFtpFileName(ApplicationConfig.FTP_IMAGE + File.separator + trfObj.getSymbFileNm()); // Ftp 다운로드 명을 설정 // 소통등급별 이미지 파일 저장 saveByteArrayToFile(trfObj, trfUpdtDt); } } // 이미지 파일저장 if (!"SBT3".equals(obj.getSymbType())) { saveByteArrayToFile(obj, updtDt); } }); } catch (Exception e) { log.error("VmsSymbService.loadVmsSymbLib: {}", e.toString()); } } public void loadVmsSymbCellInfo() { try { List infoList = this.vmsSymbMapper.selectVmsSymbCellInfo(); log.info("VmsSymbService.loadVmsSymbCellInfo: {} EA", infoList.size()); infoList.forEach(data -> { Integer symbLibNmbr = data.getSymbLibNmbr(); TbVmsSymbLibDto obj = this.symbMap.get(symbLibNmbr + "0"); if (obj == null) { log.error("VmsSymbService.loadVmsSymbCellInfo: Not Found Cell Info {}.", symbLibNmbr); return; } TbVmsSymbIfscDto cell = data.toDto(); for (Map.Entry cellObj : obj.getCellMap().entrySet()) { if (cellObj.getValue().getVmsIfscId().equals(cell.getVmsIfscId())) { cell.setDup(true); break; } } obj.getCellMap().put(cell.getCellId(), cell); }); } catch (Exception e) { log.error("VmsSymbService.loadVmsSymbCellInfo: {}", e.getMessage()); } } public void saveByteArrayToFile(TbVmsSymbLibDto obj, String updtDt) { File imagFile = new File(obj.getLocalFileName()); if (!imagFile.exists() || !obj.getUpdtDt().equals(updtDt)) { if (imagFile.exists()) { boolean deleted = imagFile.delete(); log.info("VmsSymbService.saveImageFile: Old file deleted {}, {}", obj.getLocalFileName(), deleted); } ItsUtils.saveByteArrayToFile(obj.getLocalFileName(), obj.getImagData()); } obj.setUpdtDt(updtDt); // 업데이트 시각을 업데이트 한다. } public static int getGradColor(int grad) { if (grad == 1) return Color.GREEN.getRGB(); if (grad == 2) return Color.YELLOW.getRGB(); if (grad == 3) return Color.RED.getRGB(); return Color.GRAY.getRGB(); } public static Color getTrafColor(int grad) { if (grad == 1) return Color.GREEN; if (grad == 2) return Color.YELLOW; if (grad == 3) return Color.RED; return Color.GRAY; } }