Browse Source

Merge commit '946945e86ba7ef82edaade24dc518b47c6a74531' into feature/lannc/pdf-download

pull/4/head
lkd9125 1 year ago
parent
commit
4207cc4071
  1. 33
      pav-server/src/main/java/com/palnet/biz/api/bas/flight/controller/BasFlightController.java
  2. 193
      pav-server/src/main/java/com/palnet/biz/api/bas/flight/service/BasFlightService.java
  3. 109
      pav-server/src/main/java/com/palnet/biz/api/bas/flight/template/service/TemplateService.java
  4. 6
      pav-server/src/main/java/com/palnet/biz/api/bas/flight/template/vo/LaancPdfVO.java
  5. 2
      pav-server/src/main/java/com/palnet/biz/api/bas/flight/template/vo/PdfBaseVO.java
  6. 26
      pav-server/src/main/java/com/palnet/biz/api/external/model/PilotValidRq.java
  7. 30
      pav-server/src/main/java/com/palnet/biz/api/external/model/PilotValidRs.java
  8. 41
      pav-server/src/main/java/com/palnet/biz/api/external/service/TsService.java
  9. 2
      pav-server/src/main/java/com/palnet/biz/jpa/entity/FltPlanBas.java
  10. 5
      pav-server/src/main/java/com/palnet/comn/code/ErrorCode.java
  11. 456
      pav-server/src/main/java/com/palnet/comn/utils/AirspaceUtils.java
  12. 6
      pav-server/src/main/java/com/palnet/comn/utils/AreaUtils.java
  13. 83
      pav-server/src/main/java/com/palnet/comn/utils/PdfUtils.java
  14. 14781
      pav-server/src/main/resources/air/airgeo.json
  15. 25326
      pav-server/src/main/resources/air/elev2d/airgeo-elev.json
  16. 5891
      pav-server/src/main/resources/air/elev2d/gimpo-airport-2d-elev.json
  17. 5
      pav-server/src/main/resources/air/sample/airgeo-3d.json
  18. 1820
      pav-server/src/main/resources/air/sample/airgeo-gimpo-airport.json
  19. 14786
      pav-server/src/main/resources/air/sample/gimpo-airport-2d-square.json
  20. 5
      pav-server/src/main/resources/air/sample/gimpo-airport-3d.json

33
pav-server/src/main/java/com/palnet/biz/api/bas/flight/controller/BasFlightController.java

@ -26,8 +26,9 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import com.palnet.biz.api.bas.flight.dto.LanncPdfVO;
import com.palnet.biz.api.bas.flight.service.BasFlightService; import com.palnet.biz.api.bas.flight.service.BasFlightService;
import com.palnet.biz.api.bas.flight.template.service.TemplateService;
import com.palnet.biz.api.bas.flight.template.vo.LaancPdfVO;
import com.palnet.biz.api.comn.model.ComnPagingRs; import com.palnet.biz.api.comn.model.ComnPagingRs;
import com.palnet.biz.api.comn.response.BasicResponse; import com.palnet.biz.api.comn.response.BasicResponse;
import com.palnet.biz.api.comn.response.ErrorResponse; import com.palnet.biz.api.comn.response.ErrorResponse;
@ -53,14 +54,18 @@ public class BasFlightController {
private final Environment env; private final Environment env;
private final CtrTrnsLctnService ctrTrnsLctnService; private final CtrTrnsLctnService ctrTrnsLctnService;
private final AreaUtils utils; private final AreaUtils utils;
private final PdfUtils pdfUtils; private final TemplateService templateService;
private final PdfUtils pdfUtils;
@Autowired @Autowired
public BasFlightController(BasFlightService basFlightService, Environment env, CtrTrnsLctnService ctrTrnsLctnService, AreaUtils AreaUtils, PdfUtils pdfUtils) { public BasFlightController(BasFlightService basFlightService, Environment env, CtrTrnsLctnService ctrTrnsLctnService, AreaUtils AreaUtils, TemplateService templateService, PdfUtils pdfUtils) {
this.basFlightService = basFlightService; this.basFlightService = basFlightService;
this.env = env; this.env = env;
this.ctrTrnsLctnService = ctrTrnsLctnService; this.ctrTrnsLctnService = ctrTrnsLctnService;
this.utils = AreaUtils; this.utils = AreaUtils;
this.templateService = templateService;
this.pdfUtils = pdfUtils; this.pdfUtils = pdfUtils;
} }
@ -392,24 +397,20 @@ public class BasFlightController {
@PostMapping("/laanc-pdf/create") @PostMapping("/laanc-pdf/create")
@Tag(name = "비행계획서", description = "비행계획서 관련 API") @Tag(name = "비행계획서", description = "비행계획서 관련 API")
@ApiOperation(value = "Lannc 공문 PDF생성") @ApiOperation(value = "Laanc 공문 PDF생성")
public void createLancePDF(@RequestBody LanncPdfVO vo) { public void createLancePDF(@RequestBody LaancPdfVO vo) {
String airUser = vo.getUserName(); // PDF 생성 및 저장
String etc = String.valueOf(System.currentTimeMillis()); // 동명이인 방지 ComFileBas comFileBas = templateService.makeLaancPdf(vo);
String fileName = pdfUtils.getSaveName(airUser, etc);
// DB 저장
// PDF 생성 및 저장 templateService.save(comFileBas);
String htmlContent = pdfUtils.getHtmlToString(vo);
ComFileBas comFileBas = pdfUtils.generatePDF(htmlContent, fileName);
pdfUtils.save(comFileBas);
} }
@GetMapping("/laanc-pdf/download") @GetMapping("/laanc-pdf/download")
public void downloadPDF(int fileSno, HttpServletResponse response){ public void downloadPDF(int fileSno, HttpServletResponse response){
basFlightService.fileDownload(fileSno, response); // basFlightService.fileDownload(fileSno, response);
} }
} }

193
pav-server/src/main/java/com/palnet/biz/api/bas/flight/service/BasFlightService.java

@ -1,5 +1,37 @@
package com.palnet.biz.api.bas.flight.service; package com.palnet.biz.api.bas.flight.service;
import com.palnet.biz.api.acnt.jwt.model.JwtGroupModel;
import com.palnet.biz.api.acnt.jwt.utils.JwtTokenUtil;
import com.palnet.biz.api.bas.flight.model.*;
import com.palnet.biz.api.bas.group.model.BasGroupJoinModel;
import com.palnet.biz.api.comn.model.ComnPagingRs;
import com.palnet.biz.api.external.model.PilotValidRq;
import com.palnet.biz.api.external.model.PilotValidRs;
import com.palnet.biz.api.external.service.TsService;
import com.palnet.biz.jpa.entity.*;
import com.palnet.biz.jpa.repository.flt.*;
import com.palnet.biz.jpa.repository.pty.PtyGroupQueryRepository;
import com.palnet.biz.scheduler.ctr.model.CtrTrnsLctnModel;
import com.palnet.biz.scheduler.ctr.service.CtrTrnsLctnService;
import com.palnet.comn.utils.AirspaceUtils;
import com.palnet.comn.utils.AreaUtils;
import com.palnet.comn.utils.EncryptUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -16,55 +48,14 @@ import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.palnet.biz.api.bas.flight.model.*;
import org.apache.commons.lang3.StringUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.locationtech.jts.geom.Coordinate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.palnet.biz.api.acnt.jwt.model.JwtGroupModel;
import com.palnet.biz.api.acnt.jwt.utils.JwtTokenUtil;
import com.palnet.biz.api.bas.group.model.BasGroupJoinModel;
import com.palnet.biz.api.comn.model.ComnPagingRs;
import com.palnet.biz.jpa.entity.ComFileBas;
import com.palnet.biz.jpa.entity.FltPlanArcrft;
import com.palnet.biz.jpa.entity.FltPlanArea;
import com.palnet.biz.jpa.entity.FltPlanAreaCoord;
import com.palnet.biz.jpa.entity.FltPlanBas;
import com.palnet.biz.jpa.entity.FltPlanPilot;
import com.palnet.biz.jpa.repository.com.ComFileBasRepository;
import com.palnet.biz.jpa.repository.flt.FltPlanArcrftRepository;
import com.palnet.biz.jpa.repository.flt.FltPlanAreaCoordRepository;
import com.palnet.biz.jpa.repository.flt.FltPlanAreaRepository;
import com.palnet.biz.jpa.repository.flt.FltPlanBasRepository;
import com.palnet.biz.jpa.repository.flt.FltPlanPilotRepository;
import com.palnet.biz.jpa.repository.flt.FltPlanQueryRepository;
import com.palnet.biz.jpa.repository.pty.PtyGroupQueryRepository;
import com.palnet.biz.scheduler.ctr.model.CtrTrnsLctnModel;
import com.palnet.biz.scheduler.ctr.service.CtrTrnsLctnService;
import com.palnet.comn.code.ErrorCode;
import com.palnet.comn.exception.CustomException;
import com.palnet.comn.utils.AreaUtils;
import com.palnet.comn.utils.EncryptUtils;
import lombok.extern.log4j.Log4j2; @Slf4j
@RequiredArgsConstructor
@Log4j2
@Service @Service
@Transactional(readOnly = true) @Transactional(readOnly = true)
public class BasFlightService { public class BasFlightService {
@Autowired private final CtrTrnsLctnService ctrTrnsLctnService;
private CtrTrnsLctnService ctrTrnsLctnService;
private final FltPlanBasRepository fltPlanBasRepository; private final FltPlanBasRepository fltPlanBasRepository;
private final FltPlanArcrftRepository fltPlanArcrftRepository; private final FltPlanArcrftRepository fltPlanArcrftRepository;
private final FltPlanAreaRepository fltPlanAreaRepository; private final FltPlanAreaRepository fltPlanAreaRepository;
@ -72,31 +63,10 @@ public class BasFlightService {
private final FltPlanPilotRepository fltPlanPilotRepository; private final FltPlanPilotRepository fltPlanPilotRepository;
private final FltPlanQueryRepository fltPlanQueryRepository; private final FltPlanQueryRepository fltPlanQueryRepository;
private final PtyGroupQueryRepository ptyPlanQueryRepository; private final PtyGroupQueryRepository ptyPlanQueryRepository;
private final ComFileBasRepository comFileBasRepository; private final TsService tsService;
private final JwtTokenUtil jwtTokenUtil; private final JwtTokenUtil jwtTokenUtil;
private final AreaUtils areaUtils; private final AreaUtils areaUtils;
public BasFlightService(FltPlanBasRepository fltPlanBasRepository,
FltPlanArcrftRepository fltPlanArcrftRepository,
FltPlanAreaRepository fltPlanAreaRepository,
FltPlanAreaCoordRepository fltPlanAreaCoordRepository,
FltPlanPilotRepository fltPlanPilotRepository,
FltPlanQueryRepository fltPlanQueryRepository,
PtyGroupQueryRepository ptyPlanQueryRepository,
JwtTokenUtil jwtTokenUtil,
AreaUtils areaUtils,
ComFileBasRepository comFileBasRepository) {
this.fltPlanBasRepository = fltPlanBasRepository;
this.fltPlanArcrftRepository = fltPlanArcrftRepository;
this.fltPlanAreaRepository = fltPlanAreaRepository;
this.fltPlanAreaCoordRepository = fltPlanAreaCoordRepository;
this.fltPlanPilotRepository = fltPlanPilotRepository;
this.fltPlanQueryRepository = fltPlanQueryRepository;
this.ptyPlanQueryRepository = ptyPlanQueryRepository;
this.jwtTokenUtil = jwtTokenUtil;
this.areaUtils = areaUtils;
this.comFileBasRepository = comFileBasRepository;
}
// 비행계획서 조회 // 비행계획서 조회
public ComnPagingRs<BasFlightPlanModel> listPlan(BasFlightPlanListRq rq) { public ComnPagingRs<BasFlightPlanModel> listPlan(BasFlightPlanListRq rq) {
@ -189,6 +159,7 @@ public class BasFlightService {
.planAreaDuplicatdYn("N") .planAreaDuplicatdYn("N")
.build(); .build();
boolean isEqualsFltElev = false; boolean isEqualsFltElev = false;
List<BasFlightPlanAreaModel> rqAreaList = rq.getAreaList(); List<BasFlightPlanAreaModel> rqAreaList = rq.getAreaList();
String rqFltElev = rqAreaList.get(0).getFltElev(); String rqFltElev = rqAreaList.get(0).getFltElev();
@ -301,6 +272,35 @@ public class BasFlightService {
} }
} }
// 공역 중복 확인
for (BasFlightPlanAreaModel rqArea : rq.getAreaList()) {
List<Coordinate> rqCoord = new ArrayList<>();
List<Coordinate> rqCoordBufferList = new ArrayList<>();
//rq로 들어온 좌표로 버퍼좌표 생성
for (BasFlightPlanAreaCoordModel coord : rqArea.getCoordList()) {
Coordinate coords = new Coordinate(coord.getLon(), coord.getLat());
rqCoord.add(coords);
}
if ("LINE".equals(rqArea.getAreaType())) {
List<Coordinate> trans = areaUtils.transform(rqCoord, "EPSG:4326", "EPSG:5181");
List<Coordinate> bufferList = areaUtils.buffer(trans, rqArea.getBufferZone());
rqCoordBufferList = areaUtils.transform(bufferList, "EPSG:5181", "EPSG:4326");
} else if ("POLYGON".equals(rqArea.getAreaType())) {
rqCoordBufferList.addAll(rqCoord);
} else if ("CIRCLE".equals(rqArea.getAreaType())) {
rqCoordBufferList = areaUtils.createCircle(rqCoord.get(0), rqArea.getBufferZone());
}
AirspaceUtils airspaceUtils = AirspaceUtils.getInstance();
Geometry rqGeometry = airspaceUtils.createGeometryByCoordinate(rqCoordBufferList);
Integer fltElev = Integer.valueOf(rqArea.getFltElev());
if(fltElev == null) fltElev = 0;
AirspaceUtils.FeatureInfo featureInfo = new AirspaceUtils.FeatureInfo(null, null, 0, fltElev, rqGeometry);
boolean duplicatedAirspace = airspaceUtils.isDuplicatedAirspace(featureInfo);
rs.setAirspaceDuplicatedYn(duplicatedAirspace ? "Y" : "N");
}
return rs; return rs;
} }
@ -310,12 +310,22 @@ public class BasFlightService {
// 비행계획서 유효성 검사. // 비행계획서 유효성 검사.
BasFlightPlanLaancRs rs = this.planValid(rq); BasFlightPlanLaancRs rs = this.planValid(rq);
// TODO 공역 중복 확인
rs.setAirspaceDuplicatedYn("N");
// TODO 조종사 자격 및 기체보험 확인 // TODO 조종사 자격 및 기체보험 확인
rs.setPilotQlfcYn("Y"); PilotValidRq pilotValidRq = PilotValidRq.builder()
rs.setAcrftInsuranceYn("Y"); .pilotci("조종사CI")
.declarationnum("기체신고번호")
.build();
PilotValidRs pilotValidRs = tsService.callPilotValid(pilotValidRq);
if(pilotValidRs == null){
rs.setPilotQlfcYn("N");
rs.setAcrftInsuranceYn("N");
} else {
rs.setPilotQlfcYn(pilotValidRs.getPilotcredentialyn());
rs.setAcrftInsuranceYn(pilotValidRs.getArcrftinsuranceyn());
}
// TODO LAANC가 검증된것들만 DB저장 - LAANC가 미승인이라도 저장해야하는지 확인 필요
if(!rs.isValid()) return rs; if(!rs.isValid()) return rs;
// 비행계획서 // 비행계획서
@ -325,6 +335,10 @@ public class BasFlightService {
basEntity.setAprvlYn("N"); basEntity.setAprvlYn("N");
basEntity.setCreateUserId(userId); basEntity.setCreateUserId(userId);
basEntity.setUpdateUserId(userId); basEntity.setUpdateUserId(userId);
// 사업자 유무 - TS 데이터
basEntity.setCorpRegYn(pilotValidRs.getCorpregyn()); // 사업자유무
basEntity.setServiceType("PAV-KAC");
FltPlanBas rBasEntity = fltPlanBasRepository.save(basEntity); FltPlanBas rBasEntity = fltPlanBasRepository.save(basEntity);
Integer planSno = rBasEntity.getPlanSno(); Integer planSno = rBasEntity.getPlanSno();
// 비행구역 // 비행구역
@ -335,6 +349,7 @@ public class BasFlightService {
areaEntity.setPlanSno(planSno); areaEntity.setPlanSno(planSno);
areaEntity.setCreateUserId(userId); areaEntity.setCreateUserId(userId);
areaEntity.setUpdateUserId(userId); areaEntity.setUpdateUserId(userId);
FltPlanArea rAreaEntity = fltPlanAreaRepository.save(areaEntity); FltPlanArea rAreaEntity = fltPlanAreaRepository.save(areaEntity);
Integer planAreaSno = rAreaEntity.getPlanAreaSno(); Integer planAreaSno = rAreaEntity.getPlanAreaSno();
List<BasFlightPlanAreaCoordModel> coordModelList = areaModel.getCoordList(); List<BasFlightPlanAreaCoordModel> coordModelList = areaModel.getCoordList();
@ -370,6 +385,10 @@ public class BasFlightService {
arcrftEntity.setPlanSno(planSno); arcrftEntity.setPlanSno(planSno);
arcrftEntity.setCreateUserId(userId); arcrftEntity.setCreateUserId(userId);
arcrftEntity.setUpdateUserId(userId); arcrftEntity.setUpdateUserId(userId);
// 추가 필드
arcrftEntity.setAcrftInsuranceYn(pilotValidRs.getArcrftinsuranceyn()); // 보험여부
// arcrftEntity.setInsuranceExperiod(null); // 보헌 유효기간
// arcrftEntity.setCorporationNm(null); // 법인명
fltPlanArcrftRepository.save(arcrftEntity); fltPlanArcrftRepository.save(arcrftEntity);
} }
} }
@ -380,15 +399,24 @@ public class BasFlightService {
@Transactional @Transactional
public BasFlightPlanLaancRs updatePlan(BasFlightPlanModel rq) { public BasFlightPlanLaancRs updatePlan(BasFlightPlanModel rq) {
// 비행계획서 유효성 검사.
// 비행계획서 유효성 검사. // 비행계획서 유효성 검사.
BasFlightPlanLaancRs rs = this.planValid(rq); BasFlightPlanLaancRs rs = this.planValid(rq);
// TODO 공역 중복 확인
rs.setAirspaceDuplicatedYn("N");
// TODO 조종사 자격 및 기체보험 확인 // TODO 조종사 자격 및 기체보험 확인
rs.setPilotQlfcYn("Y"); PilotValidRq pilotValidRq = PilotValidRq.builder()
rs.setAcrftInsuranceYn("Y"); .pilotci("조종사CI")
.declarationnum("기체신고번호")
.build();
PilotValidRs pilotValidRs = tsService.callPilotValid(pilotValidRq);
if(pilotValidRs == null){
rs.setPilotQlfcYn("N");
rs.setAcrftInsuranceYn("N");
} else {
rs.setPilotQlfcYn(pilotValidRs.getPilotcredentialyn());
rs.setAcrftInsuranceYn(pilotValidRs.getArcrftinsuranceyn());
}
// LAANC가 검증된것들만 DB저장
if(!rs.isValid()) return rs; if(!rs.isValid()) return rs;
if (rq != null && rq.getPlanSno() != null) { if (rq != null && rq.getPlanSno() != null) {
@ -398,6 +426,10 @@ public class BasFlightService {
FltPlanBas planEntity = fltPlanBasRepository.findById(planSno).orElseThrow(); FltPlanBas planEntity = fltPlanBasRepository.findById(planSno).orElseThrow();
BasFlightMapper.mapper.updateEntityByModel(planEntity, rq); BasFlightMapper.mapper.updateEntityByModel(planEntity, rq);
planEntity.setUpdateUserId(userId); planEntity.setUpdateUserId(userId);
// 사업자 유무 - TS 데이터
planEntity.setCorpRegYn(pilotValidRs.getCorpregyn()); // 사업자유무
// planEntity.setServiceType("PAV-KAC");
fltPlanBasRepository.save(planEntity); fltPlanBasRepository.save(planEntity);
// 비행구역 // 비행구역
@ -414,6 +446,7 @@ public class BasFlightService {
BasFlightMapper.mapper.updateEntityByModel(areaEntity, areaModel); BasFlightMapper.mapper.updateEntityByModel(areaEntity, areaModel);
} }
areaEntity.setUpdateUserId(userId); areaEntity.setUpdateUserId(userId);
fltPlanAreaRepository.save(areaEntity); fltPlanAreaRepository.save(areaEntity);
@ -495,6 +528,8 @@ public class BasFlightService {
} else { } else {
BasFlightMapper.mapper.updateEntityByModel(arcrftEntity, arcrftModel); BasFlightMapper.mapper.updateEntityByModel(arcrftEntity, arcrftModel);
} }
// 추가 필드
arcrftEntity.setAcrftInsuranceYn(pilotValidRs.getArcrftinsuranceyn()); // 보험여부
fltPlanArcrftRepository.save(arcrftEntity); fltPlanArcrftRepository.save(arcrftEntity);
} }
List<FltPlanArcrft> deleteArcrftEntity = arcrftEntityList.stream().filter(fltPlanArcrft -> { List<FltPlanArcrft> deleteArcrftEntity = arcrftEntityList.stream().filter(fltPlanArcrft -> {
@ -756,11 +791,5 @@ public class BasFlightService {
return jsonObject; return jsonObject;
} }
public void fileDownload(int fileSno, HttpServletResponse response) throws CustomException{
ComFileBas comFileBas = comFileBasRepository.findById(fileSno).orElse(null);
if(comFileBas == null) throw new CustomException(ErrorCode.DATA_NOTFIND);
}
} }

109
pav-server/src/main/java/com/palnet/biz/api/bas/flight/template/service/TemplateService.java

@ -0,0 +1,109 @@
package com.palnet.biz.api.bas.flight.template.service;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.Map;
import java.util.Map.Entry;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.palnet.biz.api.acnt.jwt.utils.JwtTokenUtil;
import com.palnet.biz.api.bas.flight.template.vo.LaancPdfVO;
import com.palnet.biz.jpa.entity.ComFileBas;
import com.palnet.biz.jpa.repository.com.ComFileBasRepository;
import com.palnet.comn.utils.InstantUtils;
import com.palnet.comn.utils.PdfUtils;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class TemplateService {
@Autowired
private PdfUtils pdfUtils;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private ComFileBasRepository comFileBasRepository;
@Value("${base-url}")
private String BASE_PATH;
private final String FILE_EXTENSION = ".pdf";
/**
* 파일명 만들기, 앞에 기본으로 금일 날짜있음
* [예시] 20230102_[추가파라미터]
* @param etcName
* @return
*/
private String getLaancSaveName(String ...etcName){
String date = InstantUtils.toDateString(Instant.now()).replace("-", "");
StringBuilder result = new StringBuilder();
result.append(date);
for(String name : etcName){
result.append("-")
.append(name);
}
result.append(this.FILE_EXTENSION);
return result.toString();
}
/**
* PDF 생성
* @param vo
* @return
*/
public ComFileBas makeLaancPdf(LaancPdfVO vo){
String airUser = vo.getUserName();
String etc = String.valueOf(System.currentTimeMillis()); // 동명이인 방지
String fileName = getLaancSaveName(airUser, etc);
String htmlContent = pdfUtils.getHtmlToString(vo);
ComFileBas comFileBas = pdfUtils.generatePDF(htmlContent, fileName);
String userId = jwtTokenUtil.getUserIdByToken();
comFileBas.setCreateUserId(userId);
return comFileBas;
}
/**
* DB 인서트, 최신데이터 가져온 Group NO 1추가함
* @param comFileBas
*/
@Transactional
public void save(ComFileBas comFileBas){
// DB Insert
ComFileBas lastComFileBas = comFileBasRepository.findFirstByOrderByFileSnoDesc();
int fileGroupNo = (lastComFileBas == null) ? 1 : lastComFileBas.getFileGroupNo() + 1;
comFileBas.setFileGroupNo(fileGroupNo);
comFileBasRepository.save(comFileBas);
}
}

6
pav-server/src/main/java/com/palnet/biz/api/bas/flight/dto/LanncPdfVO.java → pav-server/src/main/java/com/palnet/biz/api/bas/flight/template/vo/LaancPdfVO.java

@ -1,4 +1,4 @@
package com.palnet.biz.api.bas.flight.dto; package com.palnet.biz.api.bas.flight.template.vo;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.HashMap; import java.util.HashMap;
@ -10,7 +10,7 @@ import lombok.ToString;
@Getter @Getter
@Setter @Setter
@ToString @ToString
public class LanncPdfVO extends PdfBaseVO{ public class LaancPdfVO extends PdfBaseVO{
// TODO : 아직 파라미터가 정해지지 않음 // TODO : 아직 파라미터가 정해지지 않음
private String userName; // 조종사 이름 private String userName; // 조종사 이름
@ -20,7 +20,7 @@ public class LanncPdfVO extends PdfBaseVO{
private String userGender; // 조종사 성별 private String userGender; // 조종사 성별
public LanncPdfVO (){ public LaancPdfVO (){
init(); init();
} }

2
pav-server/src/main/java/com/palnet/biz/api/bas/flight/dto/PdfBaseVO.java → pav-server/src/main/java/com/palnet/biz/api/bas/flight/template/vo/PdfBaseVO.java

@ -1,4 +1,4 @@
package com.palnet.biz.api.bas.flight.dto; package com.palnet.biz.api.bas.flight.template.vo;
import java.util.Map; import java.util.Map;

26
pav-server/src/main/java/com/palnet/biz/api/external/model/PilotValidRq.java vendored

@ -0,0 +1,26 @@
package com.palnet.biz.api.external.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* packageName : com.palnet.biz.api.external.model
* fileName : PilotValidRq
* author : dhji
* date : 2023-09-21(021)
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2023-09-21(021) dhji 최초 생성
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PilotValidRq {
private String pilotci; // 조종사 ci - 본인인증
private String declarationnum; // 기체신고번호
}

30
pav-server/src/main/java/com/palnet/biz/api/external/model/PilotValidRs.java vendored

@ -0,0 +1,30 @@
package com.palnet.biz.api.external.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* packageName : com.palnet.biz.api.external.model
* fileName : PilotValidRq
* author : dhji
* date : 2023-09-21(021)
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2023-09-21(021) dhji 최초 생성
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PilotValidRs {
private String rspCode; // 결과코드
private String rspMessage; // 결과메시지
private String pilotcredentialyn; // 조종사자격증명여부
private String arcrftinsuranceyn; // 기체보험가입여부
private String arcrftdeclaration; // 기체신고여부
private String corpregyn; // 사업자유무
}

41
pav-server/src/main/java/com/palnet/biz/api/external/service/TsService.java vendored

@ -0,0 +1,41 @@
package com.palnet.biz.api.external.service;
import com.palnet.biz.api.external.model.PilotValidRq;
import com.palnet.biz.api.external.model.PilotValidRs;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* packageName : com.palnet.biz.api.external.service
* fileName : TsService
* author : dhji
* date : 2023-09-21(021)
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2023-09-21(021) dhji 최초 생성
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class TsService {
public PilotValidRs callPilotValid(PilotValidRq rq) {
// if(rq.getPilotci() == null || rq.getDeclarationnum() == null) {
// return null;
// }
// TODO: call pilot valid api
// RS 임시코드 - 추후 조건에 따른 TRUE/FALSE 처리 필요
PilotValidRs pilotValidRs = new PilotValidRs();
pilotValidRs.setRspCode("200");
pilotValidRs.setRspMessage("success");
pilotValidRs.setPilotcredentialyn("Y");
pilotValidRs.setArcrftinsuranceyn("Y");
pilotValidRs.setArcrftdeclaration("Y");
pilotValidRs.setCorpregyn("Y");
return pilotValidRs;
}
}

2
pav-server/src/main/java/com/palnet/biz/jpa/entity/FltPlanBas.java

@ -57,7 +57,7 @@ public class FltPlanBas {
private String aprvlYn; private String aprvlYn;
@Column(name = "APRVL_DT") @Column(name = "APRVL_DT")
private String aprvlDt; private Instant aprvlDt;
@Column(name = "DEL_YN") @Column(name = "DEL_YN")
private String delYn; private String delYn;

5
pav-server/src/main/java/com/palnet/comn/code/ErrorCode.java

@ -10,8 +10,9 @@ public enum ErrorCode {
DATA_NO("DT003", "데이터 미존재"), DATA_NO("DT003", "데이터 미존재"),
DB_ERROR("DB001" , "디비 처리중 오류"), DB_ERROR("DB001" , "디비 처리중 오류"),
PLAN_DATA_DUPLICATE("FT500", "이미 등록된 비행계획서의 비행구역과 비행시간이 일치합니다.\n비행시간 또는 비행구역을 수정하여 주십시오."), PLAN_DATA_DUPLICATE("FT500", "이미 등록된 비행계획서의 비행구역과 비행시간이 일치합니다.\n비행시간 또는 비행구역을 수정하여 주십시오."),
ARCRFT_DATA_DUPLICATE("FT500", "해당 기체는 다른 비행계획서에서 이미 등록된 기체입니다.\n비행시간 또는 기체 정보를 확인하여 주십시오."); ARCRFT_DATA_DUPLICATE("FT500", "해당 기체는 다른 비행계획서에서 이미 등록된 기체입니다.\n비행시간 또는 기체 정보를 확인하여 주십시오."),
EXTERNAL_API_ERROR("EA500", "외부서버 호출에 실패하였습니다.");
private final String code; private final String code;

456
pav-server/src/main/java/com/palnet/comn/utils/AirspaceUtils.java

@ -0,0 +1,456 @@
package com.palnet.comn.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.locationtech.jts.geom.*;
import org.opengis.feature.simple.SimpleFeature;
import org.springframework.core.io.ClassPathResource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* packageName : com.palnet.comn.utils
* fileName : AirspaceUtils
* author : dhji
* date : 2023-09-20(020)
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2023-09-20(020) dhji 최초 생성
*/
@Slf4j
public class AirspaceUtils {
private final String CLASS_PATH = "air/elev2d";
private final GeometryFactory geometryFactory = new GeometryFactory();
private List<FeatureInfo> airspaces;
private AirspaceUtils() {
log.info(">>> AirspaceUtils init...");
// 초기화
this.getResourceAirspace();
}
public static AirspaceUtils getInstance() {
return LazyHolder.INSTANCE;
}
private static class LazyHolder {
private static final AirspaceUtils INSTANCE = new AirspaceUtils();
}
// 공역 중복 검사
public boolean isDuplicatedAirspace(FeatureInfo target) {
if (this.airspaces == null || this.airspaces.isEmpty()) return true;
Integer targetHighElev = target.getHighElev();
if (targetHighElev == null) targetHighElev = 0;
Geometry targetGeometry = target.getGeometry();
for (FeatureInfo airspace : this.airspaces) {
Integer airspaceHighElev = airspace.getHighElev();
Geometry airspaceGeometry = airspace.getGeometry();
// 임시로 0~최대고도 기준으로 검증
if(airspaceHighElev <= targetHighElev) {
if (airspaceGeometry.intersects(targetGeometry)) {
return true;
}
}
}
return false;
}
public Geometry createGeometryByCoordinate(List<Coordinate> target) {
return this.createGeometryByCoordinate(target, "Polygon");
}
public Geometry createGeometryByCoordinate(List<Coordinate> target, String type) {
Geometry geometry = null;
if ("Polygon".equals(type)) {
geometry = this.geometryFactory.createPolygon(target.toArray(new Coordinate[0]));
} else if ("LineString".equals(type)) {
geometry = this.geometryFactory.createLineString(target.toArray(new Coordinate[0]));
} else if ("Point".equals(type)) {
geometry = this.geometryFactory.createPoint(target.get(0));
}
return geometry;
}
// get geometry
private List<Geometry> getAirspaceGeometry() {
return this.airspaces.stream().map(FeatureInfo::getGeometry).collect(Collectors.toList());
}
// 파일에서 공역 데이터 가져와서 geometry로 변환 - 초기화.
private void getResourceAirspace() {
ClassPathResource resource = new ClassPathResource(CLASS_PATH);
log.debug(">>> {}", resource);
List<File> geoJsonFiles = new ArrayList<>();
try {
File folder = resource.getFile();
log.debug(">>> {}", folder);
File[] files = folder.listFiles();
for (File file : files) {
if (file.isFile() && file.getName().endsWith("elev.json")) {
log.debug(">>> {}", file.getName());
geoJsonFiles.add(file);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
List<FeatureInfo> featureInfos = new ArrayList<>();
for (File file : geoJsonFiles) {
log.debug("============ {} ===================", file.getName());
try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(isr);
List<FeatureInfo> convertFeatureInfos = convertGeoJsonToGeometry(jsonObject);
featureInfos.addAll(convertFeatureInfos);
} catch (Exception e) {
log.error("ERROR : ", e);
featureInfos = null;
}
if (featureInfos != null && featureInfos.isEmpty()) {
featureInfos = null;
}
}
this.airspaces = featureInfos;
}
private List<FeatureInfo> convertGeoJsonToGeometry(JSONObject jsonObject) {
List<FeatureInfo> featureInfos = new ArrayList<>();
String type = (String) jsonObject.get("type");
if ("FeatureCollection".equals(type)) {
List<JSONObject> features = (List<JSONObject>) jsonObject.get("features");
// log.debug(">>> features size : {}", features.size());
for (JSONObject feature : features) {
JSONObject geometryObject = (JSONObject) feature.get("geometry");
String geometryType = String.valueOf(geometryObject.get("type"));
List<JSONObject> coordinatesObject = (List<JSONObject>) geometryObject.get("coordinates");
if ("Polygon".equals(geometryType)) {
List<JSONArray> innerObject = (List<JSONArray>) coordinatesObject.get(0);
JSONArray firstCoords = innerObject.get(0);
JSONArray lastCoords = innerObject.get(innerObject.size() - 1);
BigDecimal ff = new BigDecimal(String.valueOf(firstCoords.get(0)));
BigDecimal fl = new BigDecimal(String.valueOf(firstCoords.get(1)));
BigDecimal lf = new BigDecimal(String.valueOf(lastCoords.get(0)));
BigDecimal ll = new BigDecimal(String.valueOf(lastCoords.get(1)));
if (!ff.equals(lf) || !fl.equals(ll)) {
JSONObject propertiesObject = (JSONObject) feature.get("properties");
// String nameObject = String.valueOf(propertiesObject.get("name"));
// String descriptionObject = String.valueOf(propertiesObject.get("description"));
// log.info("coords first and last coords not eqauls : name/descriion = {}/{}", nameObject, descriptionObject);
innerObject.add(firstCoords);
}
}
try {
FeatureJSON featureJSON = new FeatureJSON();
SimpleFeature simpleFeature = null;
simpleFeature = featureJSON.readFeature(feature.toJSONString());
Boolean use = Boolean.valueOf(String.valueOf(simpleFeature.getAttribute("use")));
if (use) {
String name = String.valueOf(simpleFeature.getAttribute("name"));
String description = String.valueOf(simpleFeature.getAttribute("description"));
Integer lowElev = Integer.parseInt(String.valueOf(simpleFeature.getAttribute("lowElev")));
Integer highElev = Integer.parseInt(String.valueOf(simpleFeature.getAttribute("highElev")));
Geometry geometry = (Geometry) simpleFeature.getDefaultGeometry();
// log.debug(">>> name, description, use, lowElev, highElev : {}, {}, {}, {}, {}", name, description, use, lowElev, highElev);
FeatureInfo info = new FeatureInfo(name, description, lowElev, highElev, geometry);
featureInfos.add(info);
}
} catch (IOException e) {
log.error("geometry json read error : {}", e.getMessage());
}
}
} else if ("Feature".equals(type)) {
FeatureJSON featureJSON = new FeatureJSON();
try {
SimpleFeature simpleFeature = featureJSON.readFeature(jsonObject.toJSONString());
Boolean use = Boolean.valueOf(String.valueOf(simpleFeature.getAttribute("use")));
if (use) {
String name = String.valueOf(simpleFeature.getAttribute("name"));
String description = String.valueOf(simpleFeature.getAttribute("description"));
Integer lowElev = Integer.parseInt(String.valueOf(simpleFeature.getAttribute("lowElev")));
Integer highElev = Integer.parseInt(String.valueOf(simpleFeature.getAttribute("highElev")));
Geometry geometry = (Geometry) simpleFeature.getDefaultGeometry();
FeatureInfo info = new FeatureInfo(name, description, lowElev, highElev, geometry);
featureInfos.add(info);
}
} catch (IOException e) {
log.error("geometry json read error : {}", e.getMessage());
}
} else {
GeometryJSON geoJson = new GeometryJSON();
try {
Geometry geometry = geoJson.read(jsonObject.toJSONString());
FeatureInfo info = new FeatureInfo(null, null, null, null, geometry);
} catch (IOException e) {
log.error("geometry json read error : {}", e.getMessage());
}
}
return featureInfos;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class FeatureInfo {
private String name;
private String description;
private Integer lowElev;
private Integer highElev;
private Geometry geometry;
}
public static void main(String[] args) {
AirspaceUtils airspaceUtils = AirspaceUtils.getInstance();
GeometryFactory geometryFactory = new GeometryFactory();
/*
126.6186219,37.4260888
126.7662507,37.4473521
126.7223054,37.3578964
126.6186219,37.4260888
126.6828233,37.4553499
126.7456514,37.5082038
126.7796403,37.4414491
126.6828233,37.4553499
126.6750825,37.5134229
126.7804826,37.5168269
126.7679513,37.4853679
126.6750825,37.5134229
126.7679513,37.4853679
126.8074335,37.5572547
126.9097436,37.4477632
126.7679513,37.4853679
*/
log.info("=== 김포 정상 ===");
Coordinate[] polygonCoordinates6 = new Coordinate[]{
new Coordinate(126.6186219,37.4260888),
new Coordinate(126.7662507,37.4473521),
new Coordinate(126.7223054,37.3578964),
new Coordinate(126.6186219,37.4260888)
};
LinearRing linearRing6 = geometryFactory.createLinearRing(polygonCoordinates6);
Polygon polygon6 = geometryFactory.createPolygon(linearRing6);
FeatureInfo target6 = new FeatureInfo();
target6.setHighElev(0);
target6.setLowElev(0);
target6.setGeometry(polygon6);
boolean duplicatedAirspace6 = airspaceUtils.isDuplicatedAirspace(target6);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace6);
log.info("=== 김포 120m 걸침 - 100 ===");
Coordinate[] polygonCoordinates7 = new Coordinate[]{
new Coordinate(126.6828233,37.4553499),
new Coordinate(126.7456514,37.5082038),
new Coordinate(126.7796403,37.4414491),
new Coordinate(126.6828233,37.4553499)
};
LinearRing linearRing7 = geometryFactory.createLinearRing(polygonCoordinates7);
Polygon polygon7 = geometryFactory.createPolygon(linearRing7);
FeatureInfo target7 = new FeatureInfo();
target7.setHighElev(100);
target7.setLowElev(0);
target7.setGeometry(polygon7);
boolean duplicatedAirspace7 = airspaceUtils.isDuplicatedAirspace(target7);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace7);
log.info("=== 김포 120m 걸침 - 150 ===");
Coordinate[] polygonCoordinates8 = new Coordinate[]{
new Coordinate(126.6828233,37.4553499),
new Coordinate(126.7456514,37.5082038),
new Coordinate(126.7796403,37.4414491),
new Coordinate(126.6828233,37.4553499)
};
LinearRing linearRing8 = geometryFactory.createLinearRing(polygonCoordinates8);
Polygon polygon8 = geometryFactory.createPolygon(linearRing8);
FeatureInfo target8 = new FeatureInfo();
target8.setHighElev(150);
target8.setLowElev(0);
target8.setGeometry(polygon8);
boolean duplicatedAirspace8 = airspaceUtils.isDuplicatedAirspace(target8);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace8);
log.info("=== 김포 120m 걸침 - 120 ===");
Coordinate[] polygonCoordinates9 = new Coordinate[]{
new Coordinate(126.6828233,37.4553499),
new Coordinate(126.7456514,37.5082038),
new Coordinate(126.7796403,37.4414491),
new Coordinate(126.6828233,37.4553499)
};
LinearRing linearRing9 = geometryFactory.createLinearRing(polygonCoordinates9);
Polygon polygon9 = geometryFactory.createPolygon(linearRing9);
FeatureInfo target9 = new FeatureInfo();
target9.setHighElev(120);
target9.setLowElev(0);
target9.setGeometry(polygon9);
boolean duplicatedAirspace9 = airspaceUtils.isDuplicatedAirspace(target9);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace9);
log.info("=== 김포 40m 걸침 - 20 ===");
Coordinate[] polygonCoordinates10 = new Coordinate[]{
new Coordinate(126.6750825,37.5134229),
new Coordinate(126.7804826,37.5168269),
new Coordinate(126.7679513,37.4853679),
new Coordinate(126.6750825,37.5134229)
};
LinearRing linearRing10 = geometryFactory.createLinearRing(polygonCoordinates10);
Polygon polygon10 = geometryFactory.createPolygon(linearRing10);
FeatureInfo target10 = new FeatureInfo();
target10.setHighElev(20);
target10.setLowElev(0);
target10.setGeometry(polygon10);
boolean duplicatedAirspace10 = airspaceUtils.isDuplicatedAirspace(target10);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace10);
log.info("=== 김포 40m 걸침 - 100 ===");
Coordinate[] polygonCoordinates11 = new Coordinate[]{
new Coordinate(126.6750825,37.5134229),
new Coordinate(126.7804826,37.5168269),
new Coordinate(126.7679513,37.4853679),
new Coordinate(126.6750825,37.5134229)
};
LinearRing linearRing11 = geometryFactory.createLinearRing(polygonCoordinates11);
Polygon polygon11 = geometryFactory.createPolygon(linearRing11);
FeatureInfo target11 = new FeatureInfo();
target11.setHighElev(100);
target11.setLowElev(0);
target11.setGeometry(polygon11);
boolean duplicatedAirspace11 = airspaceUtils.isDuplicatedAirspace(target11);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace11);
log.info("=== 김포 40m 걸침 - 40 ===");
Coordinate[] polygonCoordinates12 = new Coordinate[]{
new Coordinate(126.6750825,37.5134229),
new Coordinate(126.7804826,37.5168269),
new Coordinate(126.7679513,37.4853679),
new Coordinate(126.6750825,37.5134229)
};
LinearRing linearRing12 = geometryFactory.createLinearRing(polygonCoordinates12);
Polygon polygon12 = geometryFactory.createPolygon(linearRing12);
FeatureInfo target12 = new FeatureInfo();
target12.setHighElev(40);
target12.setLowElev(0);
target12.setGeometry(polygon12);
boolean duplicatedAirspace12 = airspaceUtils.isDuplicatedAirspace(target12);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace12);
log.info("=== 김포 0 ===");
Coordinate[] polygonCoordinates13 = new Coordinate[]{
new Coordinate(126.7679513,37.4853679),
new Coordinate(126.8074335,37.5572547),
new Coordinate(126.9097436,37.4477632),
new Coordinate(126.7679513,37.4853679)
};
LinearRing linearRing13 = geometryFactory.createLinearRing(polygonCoordinates13);
Polygon polygon13 = geometryFactory.createPolygon(linearRing13);
FeatureInfo target13 = new FeatureInfo();
target13.setHighElev(0);
target13.setLowElev(0);
target13.setGeometry(polygon13);
boolean duplicatedAirspace13 = airspaceUtils.isDuplicatedAirspace(target13);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace13);
// 김포
// log.info("=== 김포 걸침 ===");
// Coordinate[] polygonCoordinates = new Coordinate[]{
// new Coordinate(126.6932891, 37.4789188),
// new Coordinate(126.7343162, 37.4989414),
// new Coordinate(126.729853, 37.4676111),
// new Coordinate(126.6932891, 37.4789188)
// };
// LinearRing linearRing = geometryFactory.createLinearRing(polygonCoordinates);
// Polygon polygon = geometryFactory.createPolygon(linearRing);
// FeatureInfo target = new FeatureInfo();
// target.setHighElev(0);
// target.setLowElev(0);
// target.setGeometry(polygon);
// boolean duplicatedAirspace = airspaceUtils.isDuplicatedAirspace(target);
// log.info(">>> duplicatedAirspace : {}", duplicatedAirspace);
//
// // 인천공항
// log.info("=== 인천공항 걸침 ===");
// Coordinate[] polygonCoordinates2 = new Coordinate[]{
// new Coordinate(126.57605, 37.3278721),
// new Coordinate(126.4181215, 37.4691545),
// new Coordinate(126.6351015, 37.5203648),
// new Coordinate(126.57605, 37.3278721)
// };
// LinearRing linearRing2 = geometryFactory.createLinearRing(polygonCoordinates2);
// Polygon polygon2 = geometryFactory.createPolygon(linearRing2);
// FeatureInfo target2 = new FeatureInfo();
// target2.setHighElev(0);
// target2.setLowElev(0);
// target2.setGeometry(polygon2);
// boolean duplicatedAirspace2 = airspaceUtils.isDuplicatedAirspace(target2);
// log.info(">>> duplicatedAirspace : {}", duplicatedAirspace2);
//
//
//
// // 정상
// log.info("=== 정상(안겹침) ===");
// Coordinate[] polygonCoordinates3 = new Coordinate[]{
// new Coordinate(126.6879518, 37.4444476),
// new Coordinate(126.6179139, 37.3462549),
// new Coordinate(126.7820222, 37.3528051),
// new Coordinate(126.6879518, 37.4444476)
// };
// LinearRing linearRing3 = geometryFactory.createLinearRing(polygonCoordinates3);
// Polygon polygon3 = geometryFactory.createPolygon(linearRing3);
// FeatureInfo target3 = new FeatureInfo();
// target3.setHighElev(0);
// target3.setLowElev(0);
// target3.setGeometry(polygon3);
// boolean duplicatedAirspace3 = airspaceUtils.isDuplicatedAirspace(target3);
// log.info(">>> duplicatedAirspace : {}", duplicatedAirspace3);
//
//
// // 수원 완전 포함
// log.info("=== 수원 포함 ===");
// Coordinate[] polygonCoordinates4 = new Coordinate[]{
// new Coordinate(126.9475038,37.2212829),
// new Coordinate(127.0226914,37.2857752),
// new Coordinate(127.0525605,37.192845),
// new Coordinate(126.9475038,37.2212829)
// };
// LinearRing linearRing4 = geometryFactory.createLinearRing(polygonCoordinates4);
// Polygon polygon4 = geometryFactory.createPolygon(linearRing4);
// FeatureInfo target4 = new FeatureInfo();
// target4.setHighElev(0);
// target4.setLowElev(0);
// target4.setGeometry(polygon4);
// boolean duplicatedAirspace4 = airspaceUtils.isDuplicatedAirspace(target4);
// log.info(">>> duplicatedAirspace : {}", duplicatedAirspace4);
}
}

6
pav-server/src/main/java/com/palnet/comn/utils/AreaUtils.java

@ -6,7 +6,6 @@ import org.json.simple.JSONArray;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.locationtech.jts.geom.*; import org.locationtech.jts.geom.*;
import org.locationtech.jts.geom.impl.CoordinateArraySequence;
import org.locationtech.jts.operation.buffer.BufferOp; import org.locationtech.jts.operation.buffer.BufferOp;
import org.locationtech.jts.operation.buffer.BufferParameters; import org.locationtech.jts.operation.buffer.BufferParameters;
import org.locationtech.jts.util.GeometricShapeFactory; import org.locationtech.jts.util.GeometricShapeFactory;
@ -16,10 +15,11 @@ import org.locationtech.proj4j.CoordinateReferenceSystem;
import org.locationtech.proj4j.ProjCoordinate; import org.locationtech.proj4j.ProjCoordinate;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.*; import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;

83
pav-server/src/main/java/com/palnet/comn/utils/PdfUtils.java

@ -12,8 +12,6 @@ import java.time.Instant;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -38,52 +36,21 @@ import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline; import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext; import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import com.palnet.biz.api.acnt.jwt.utils.JwtTokenUtil; import com.palnet.biz.api.acnt.jwt.utils.JwtTokenUtil;
import com.palnet.biz.api.bas.flight.dto.PdfBaseVO; import com.palnet.biz.api.bas.flight.template.vo.PdfBaseVO;
import com.palnet.biz.jpa.entity.ComFileBas; import com.palnet.biz.jpa.entity.ComFileBas;
import com.palnet.biz.jpa.repository.com.ComFileBasRepository;
import lombok.extern.slf4j.Slf4j;
@Component @Component
@Slf4j
public class PdfUtils { public class PdfUtils {
@Autowired
private TemplateEngine templateEngine;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired @Autowired
private ComFileBasRepository comFileBasRepository; private TemplateEngine templateEngine;
@Value("${base-url}") @Value("${base-url}")
private String BASE_PATH; private String BASE_PATH;
private final String FILE_EXTENSION = ".pdf"; private final String FILE_EXTENSION = ".pdf";
/**
* 파일명 만들기, 앞에 기본으로 금일 날짜있음
* [예시] 20230102_[추가파라미터]
* @param etcName
* @return
*/
public String getSaveName(String ...etcName){
String date = InstantUtils.toDateString(Instant.now()).replace("-", "");
StringBuilder result = new StringBuilder();
result.append(date);
for(String name : etcName){
result.append("-")
.append(name);
}
result.append(this.FILE_EXTENSION);
return result.toString();
}
/** /**
* Thymeleaf HTML 파일을 데이터 바인딩하여 String으로 변환 * Thymeleaf HTML 파일을 데이터 바인딩하여 String으로 변환
@ -98,8 +65,10 @@ public class PdfUtils {
// Thymeleaf 방식 html에 입힐 데이터 바인딩 // Thymeleaf 방식 html에 입힐 데이터 바인딩
Context context = new Context(); Context context = new Context();
for(Entry<String, Object> entry : param.entrySet()){ for(Entry<String, Object> entry : param.entrySet()){
context.setVariable(entry.getKey(), param.get(entry.getKey())); String key = entry.getKey();
context.setVariable(key, param.get(key));
} }
// 앞 뒤 prefix, suffix는 yml에 정의해놓음 // 앞 뒤 prefix, suffix는 yml에 정의해놓음
@ -138,7 +107,8 @@ public class PdfUtils {
pdfDocument.open(); pdfDocument.open();
/* /*
CSS 설정 TODO : 추후 템플릿 CSS 맞춰야 할것 CSS 설정
TODO : CSS 파일이 따로 있을시 임포트해주는 방법, CSS 파일 적용은 필수는 아니지만, 글꼴 적용은 꼭해야만
jar변환 CSS파일을 찾을수도 있어서 InputStream 사용 jar변환 CSS파일을 찾을수도 있어서 InputStream 사용
CSS의 색깔은 키워드로 표기 X, #e73a3a 16진법으로 표기 해야함 CSS의 색깔은 키워드로 표기 X, #e73a3a 16진법으로 표기 해야함
*/ */
@ -147,7 +117,7 @@ public class PdfUtils {
CSSResolver cssResolver = new StyleAttrCSSResolver(); CSSResolver cssResolver = new StyleAttrCSSResolver();
cssResolver.addCss(cssFile); cssResolver.addCss(cssFile);
// Font 설정 TODO : 추후 템플릿 CSS 맞춰야 할것 // Font 설정
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS); XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("static/font/NanumGothic.ttf", "NanumGothic"); fontProvider.register("static/font/NanumGothic.ttf", "NanumGothic");
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider); CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
@ -169,23 +139,19 @@ public class PdfUtils {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} catch (DocumentException e1){ } catch (DocumentException e){
e1.printStackTrace(); e.printStackTrace();
} catch (Exception e2){ } catch (Exception e){
e2.printStackTrace(); e.printStackTrace();
} }
finally{ finally{
pdfDocument.close(); pdfDocument.close();
} }
String userId = jwtTokenUtil.getUserIdByToken();
result.setFileGroupNo(0); result.setFileGroupNo(0);
result.setFilePath(this.BASE_PATH); result.setFilePath(this.BASE_PATH);
result.setFileExt(this.FILE_EXTENSION); result.setFileExt(this.FILE_EXTENSION);
result.setCreateDt(Instant.now()); result.setCreateDt(Instant.now());
result.setCreateUserId(userId);
result.setFileSaveNm(fileName); result.setFileSaveNm(fileName);
result.setFileOriNm(fileName); result.setFileOriNm(fileName);
@ -193,28 +159,11 @@ public class PdfUtils {
String filePath = result.getFileOriNm(); String filePath = result.getFileOriNm();
long fileSize = Files.size(Paths.get(pdfPath + filePath)) / 1024; long fileSize = Files.size(Paths.get(pdfPath + filePath)) / 1024;
if(fileSize > 0) result.setFileSize(String.valueOf(fileSize)); if(fileSize >= 0) result.setFileSize(String.valueOf(fileSize));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
return result; return result;
} }
/**
* DB 인서트, 최신데이터 가져온 Group NO 1추가함
* @param comFileBas
*/
@Transactional
public void save(ComFileBas comFileBas){
// DB Insert
ComFileBas lastComFileBas = comFileBasRepository.findFirstByOrderByFileSnoDesc();
int fileGroupNo = (lastComFileBas == null) ? 1 : lastComFileBas.getFileGroupNo() + 1;
comFileBas.setFileGroupNo(fileGroupNo);
comFileBasRepository.save(comFileBas);
}
} }

14781
pav-server/src/main/resources/air/airgeo.json

File diff suppressed because it is too large Load Diff

25326
pav-server/src/main/resources/air/elev2d/airgeo-elev.json

File diff suppressed because it is too large Load Diff

5891
pav-server/src/main/resources/air/elev2d/gimpo-airport-2d-elev.json

File diff suppressed because it is too large Load Diff

5
pav-server/src/main/resources/air/sample/airgeo-3d.json

@ -0,0 +1,5 @@
{
"type": "FeatureCollection",
"features": [
]
}

1820
pav-server/src/main/resources/air/sample/airgeo-gimpo-airport.json

File diff suppressed because it is too large Load Diff

14786
pav-server/src/main/resources/air/sample/gimpo-airport-2d-square.json

File diff suppressed because it is too large Load Diff

5
pav-server/src/main/resources/air/sample/gimpo-airport-3d.json

@ -0,0 +1,5 @@
{
"type": "FeatureCollection",
"features": [
]
}
Loading…
Cancel
Save