From ccaaaf1b16a119912e811c413476799ed96f3b93 Mon Sep 17 00:00:00 2001 From: qkr7828 Date: Fri, 23 Feb 2024 11:29:07 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20coordinate=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../co/palnet/kac/app/config/InitRunner.java | 34 ++ .../java/kr/co/palnet/kac/util/DmsUtils.java | 181 ++++++++++ .../co/palnet/kac/util/kisa/CoordUtils.java | 339 ++++++++++++++++++ ...tCptAuthAdmDistrictBasQueryRepository.java | 40 +++ .../flt/service/FltCptAuthDomainService.java | 18 + web/api-common/build.gradle | 2 + .../controller/ComCoordinateController.java | 61 ++++ .../model/CompotentAuthorityRQ.java | 12 + .../model/CompotentAuthorityRS.java | 17 + .../service/ComCoordinateService.java | 111 ++++++ 10 files changed, 815 insertions(+) create mode 100644 app/kac-app/src/main/java/kr/co/palnet/kac/app/config/InitRunner.java create mode 100644 common/util/src/main/java/kr/co/palnet/kac/util/DmsUtils.java create mode 100644 common/util/src/main/java/kr/co/palnet/kac/util/kisa/CoordUtils.java create mode 100644 data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltCptAuthAdmDistrictBasQueryRepository.java create mode 100644 data/flt/src/main/java/kr/co/palnet/kac/data/flt/service/FltCptAuthDomainService.java create mode 100644 web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/controller/ComCoordinateController.java create mode 100644 web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/model/CompotentAuthorityRQ.java create mode 100644 web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/model/CompotentAuthorityRS.java create mode 100644 web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/service/ComCoordinateService.java diff --git a/app/kac-app/src/main/java/kr/co/palnet/kac/app/config/InitRunner.java b/app/kac-app/src/main/java/kr/co/palnet/kac/app/config/InitRunner.java new file mode 100644 index 0000000..46518df --- /dev/null +++ b/app/kac-app/src/main/java/kr/co/palnet/kac/app/config/InitRunner.java @@ -0,0 +1,34 @@ +package kr.co.palnet.kac.app.config; + +import kr.co.palnet.kac.util.DigitalElevationModelUtils; +import kr.co.palnet.kac.util.kisa.CoordUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class InitRunner implements ApplicationRunner { + + @Override + public void run(ApplicationArguments args) throws Exception { + log.info("===== InitRunner run ====="); + // DEM(Digital Elevation Model load + try { + DigitalElevationModelUtils demUtils = DigitalElevationModelUtils.getInstance(); + log.info("DSM size : {}", demUtils.getSize()); + } catch (Exception e) { + log.warn("===== InitRunner run error[DigitalElevationModelUtils] : {}", e.getMessage()); + } + + try { + CoordUtils coordUtils = CoordUtils.getInstance(); + log.info("coord size : {}", coordUtils.getSize()); + } catch (Exception e) { + log.warn("===== cannot find coordinate file : {}", e.getMessage()); + } + + } +} + diff --git a/common/util/src/main/java/kr/co/palnet/kac/util/DmsUtils.java b/common/util/src/main/java/kr/co/palnet/kac/util/DmsUtils.java new file mode 100644 index 0000000..19dc4e7 --- /dev/null +++ b/common/util/src/main/java/kr/co/palnet/kac/util/DmsUtils.java @@ -0,0 +1,181 @@ +package kr.co.palnet.kac.util; + +import org.locationtech.jts.geom.Coordinate; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DmsUtils { + + /* 아래의 3가지 형식에 해당하는 좌표들끼리 자유롭게 변환이 가능하도록 만든 유틸리티입니다. + * RQ Sample + * DD : 41.40338, 2.17403 + * DMS : 41°24'12.2"N 2°10'26.5"E / 36° 18′ 09″ N 128° 05′ 40″ E + * DMM : 41 24.2028, 2 10.4418 + * 결과값에 오차가 조금씩 발생 할 수 있으나 Google Map 좌표상으로 무시할 수 있는 범위 내에서 발생합니다. + */ + + public static Coordinate convertDMStoDD(String DMS) { + + String regex = "(\\d+\\.?\\d*)[°]?\\s*(\\d+\\.?\\d*)[′'′]?\\s*(\\d+\\.?\\d*)[″'\"“”]?\\s*([NSEW])\\s*(\\d+\\.?\\d*)[°]?\\s*(\\d+\\.?\\d*)[′'′]?\\s*(\\d+\\.?\\d*)[″'\"“”]?\\s*([NSEW])"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(DMS); + + Coordinate coord = new Coordinate(); + if (matcher.find()) { + double latitude = Double.parseDouble(matcher.group(1)) + Double.parseDouble(matcher.group(2)) / 60.0 + Double.parseDouble(matcher.group(3)) / 3600.0; + if (matcher.group(4).equals("S") || matcher.group(4).equals("W")) { + latitude = -latitude; + } + + double longitude = Double.parseDouble(matcher.group(5)) + Double.parseDouble(matcher.group(6)) / 60.0 + Double.parseDouble(matcher.group(7)) / 3600.0; + if (matcher.group(8).equals("S") || matcher.group(8).equals("W")) { + longitude = -longitude; + } + + coord.setX(latitude); + coord.setY(longitude); + + } + + return coord; + } + + public static String convertDMStoDMM(String DMS) { + + String regex = "(\\d+\\.?\\d*)[°]?\\s*(\\d+\\.?\\d*)[′'′]?\\s*(\\d+\\.?\\d*)[″'\"“”]?\\s*([NSEW])\\s*(\\d+\\.?\\d*)[°]?\\s*(\\d+\\.?\\d*)[′'′]?\\s*(\\d+\\.?\\d*)[″'\"“”]?\\s*([NSEW])"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(DMS); + + double latitude = 0.0; + double longitude = 0.0; + + if (matcher.find()) { + latitude = Double.parseDouble(matcher.group(1)) + Double.parseDouble(matcher.group(2)) / 60.0 + Double.parseDouble(matcher.group(3)) / 3600.0; + if (matcher.group(4).equals("S") || matcher.group(4).equals("W")) { + latitude = -latitude; + } + + longitude = Double.parseDouble(matcher.group(5)) + Double.parseDouble(matcher.group(6)) / 60.0 + Double.parseDouble(matcher.group(7)) / 3600.0; + if (matcher.group(8).equals("S") || matcher.group(8).equals("W")) { + longitude = -longitude; + } + } + + latitude = Math.abs(latitude); + longitude = Math.abs(longitude); + + int latitudeDegrees = (int) latitude; + int longitudeDegrees = (int) longitude; + + double latitudeMinutes = (latitude - latitudeDegrees) * 60.0; + double longitudeMinutes = (longitude - longitudeDegrees) * 60.0; + + String result = String.format("%d %02.4f %d %02.4f", latitudeDegrees, latitudeMinutes, longitudeDegrees, longitudeMinutes); + + return result; + + } + + public static String convertDDtoDMM(Coordinate DD) { + + double latitude = DD.x; + double longitude = DD.y; + char latitudeDirection = (latitude >= 0) ? 'N' : 'S'; + char longitudeDirection = (longitude >= 0) ? 'E' : 'W'; + + latitude = Math.abs(latitude); + longitude = Math.abs(longitude); + + int latitudeDegrees = (int) latitude; + int longitudeDegrees = (int) longitude; + + double latitudeMinutes = (latitude - latitudeDegrees) * 60.0; + double longitudeMinutes = (longitude - longitudeDegrees) * 60.0; + + String result = String.format("%d %02.4f %c %d %02.4f %c", latitudeDegrees, latitudeMinutes, latitudeDirection, longitudeDegrees, longitudeMinutes, longitudeDirection); + + return result; + + } + + public static String convertDDtoDMS(Coordinate DD) { + double latitude = DD.x; + double longitude = DD.y; + + char latitudeDirection = (latitude >= 0) ? 'N' : 'S'; + char longitudeDirection = (longitude >= 0) ? 'E' : 'W'; + + latitude = Math.abs(latitude); + longitude = Math.abs(longitude); + + int latitudeDegrees = (int) Math.floor(latitude); + int longitudeDegrees = (int) Math.floor(longitude); + + double latitudeMinutes = (latitude - latitudeDegrees) * 60; + double longitudeMinutes = (longitude - longitudeDegrees) * 60; + + int latitudeSeconds = (int) ((latitudeMinutes - (int) latitudeMinutes) * 60); + int longitudeSeconds = (int) ((longitudeMinutes - (int) longitudeMinutes) * 60); + + String result = String.format("%d° %02d′ %02d″ %c, %d° %02d′ %02d″ %c", + latitudeDegrees, (int) latitudeMinutes, latitudeSeconds, latitudeDirection, + longitudeDegrees, (int) longitudeMinutes, longitudeSeconds, longitudeDirection); + + return result; + } + + public static String convertDMMtoDD(String DMM) { + + String[] parts = DMM.split(", "); + + String result = ""; + if (parts.length == 2) { + String[] latParts = parts[0].split(" "); + String[] lonParts = parts[1].split(" "); + + if (latParts.length == 2 && lonParts.length == 2) { + int latDegrees = Integer.parseInt(latParts[0]); + double latMinutes = Double.parseDouble(latParts[1]); + + int lonDegrees = Integer.parseInt(lonParts[0]); + double lonMinutes = Double.parseDouble(lonParts[1]); + + double latitude = latDegrees + latMinutes / 60.0; + double longitude = lonDegrees + lonMinutes / 60.0; + + result = String.format("%.5f, %.5f%n", latitude, longitude); + } + } + return result; + } + + public static String convertDMMtoDMS(String DMM) { + + String[] parts = DMM.split(", "); + + String dmsCoordinates = ""; + + if (parts.length == 2) { + String[] latParts = parts[0].split(" "); + String[] lonParts = parts[1].split(" "); + + if (latParts.length == 2 && lonParts.length == 2) { + int latDegrees = Integer.parseInt(latParts[0]); + double latMinutes = Double.parseDouble(latParts[1]); + + int lonDegrees = Integer.parseInt(lonParts[0]); + double lonMinutes = Double.parseDouble(lonParts[1]); + + double latDMSMinutes = (latMinutes - (int) latMinutes) * 60.0; + double lonDMSMinutes = (lonMinutes - (int) lonMinutes) * 60.0; + + dmsCoordinates = String.format("%d°%02d'%04.1f\"N %d°%02d'%04.1f\"E", latDegrees, (int) latMinutes, latDMSMinutes, lonDegrees, (int) lonMinutes, lonDMSMinutes); + + } + } + + return dmsCoordinates; + } + +} \ No newline at end of file diff --git a/common/util/src/main/java/kr/co/palnet/kac/util/kisa/CoordUtils.java b/common/util/src/main/java/kr/co/palnet/kac/util/kisa/CoordUtils.java new file mode 100644 index 0000000..8437f2c --- /dev/null +++ b/common/util/src/main/java/kr/co/palnet/kac/util/kisa/CoordUtils.java @@ -0,0 +1,339 @@ +package kr.co.palnet.kac.util.kisa; + +import lombok.extern.slf4j.Slf4j; +import org.json.simple.JSONArray; +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.GeometryFactory; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.*; + +@Slf4j +public class CoordUtils { + + private String basePath = "C:/Users/Jaewoo/Downloads/pal/pav/kac/coordinate/coordinateFolderNew/"; + + private static final CoordUtils INSTANCE = new CoordUtils(); + + private String baseFileName = "all_location.geojson"; + + private List allLocation; + + private GeometryFactory geometryFactory = new GeometryFactory(); + + private CoordUtils() { + + this.locationInit(); + } + + public static CoordUtils getInstance() { + return INSTANCE; + } + + public int getSize() { + if(this.allLocation == null) return 0; + return this.allLocation.size(); + } + + public void locationInit() { + + List result = new ArrayList(); + + ExecutorService executorService = Executors.newFixedThreadPool(10); + + Integer[] coords = {11, 26, 27, 28, 29, 30, 31, 36, 41, 43, 44, 45, 46, 47, 48, 50, 51}; + + List> callables = new ArrayList<>(); + + for (int i = 0; i < coords.length; i++) { + + int path = i; + callables.add(() -> initCoordinates(coords[path])); + + } + + try { + + List> results = new ArrayList<>(); + + for (Callable callable : callables) { + results.add(executorService.submit(callable)); + } + + executorService.shutdown(); + + for (Future rslt : results) { + + result.add(rslt.get()); + + } + } catch (Exception e) { + e.printStackTrace(); + } + + this.allLocation = result; + + } + + public JSONObject initCoordinates(Integer coords) { + + JSONObject jsonObject = new JSONObject(); + + String path = basePath + coords + "/" + baseFileName; + + try(InputStream inputStream = new FileInputStream(path); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8192)) { + + JSONParser jsonParser = new JSONParser(); + + jsonObject = (JSONObject) jsonParser.parse(reader); + + }catch(Exception e) { + + e.getStackTrace(); + + } + return jsonObject; + } + + public JSONObject getPlace(Coordinate coord) throws IOException, ParseException { + + int numberOfThreads = 5; + ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads); + + String address = ""; + + String depth = ""; + + Double distance = 1000000.0; + + List> callables = new ArrayList<>(); + + for (int i = 0; i < allLocation.size(); i++) { + + int path = i; + callables.add(() -> getCoordinateGis(coord, allLocation.get(path))); + + } + + try { + + List> results = new ArrayList<>(); + + for (Callable callable : callables) { + results.add(executorService.submit(callable)); + } + + executorService.shutdown(); + + for (Future rslt : results) { + + JSONObject jsonObject = new JSONObject(); + + try { + + jsonObject = rslt.get(); + + } catch (InterruptedException | ExecutionException e) { + + jsonObject = null; + } + + if(jsonObject != null && jsonObject.get("distance") == null) { + + depth = (String) jsonObject.get("CD"); + + address = jsonObject.get("KOR_NM").toString(); + + break; + + } else if(jsonObject != null && jsonObject.get("distance") != null) { + + Double distances = (Double) jsonObject.get("distance"); + + if(distance > distances) { + + distance = distances; + + depth = (String) jsonObject.get("CD"); + + address = jsonObject.get("KOR_NM").toString(); + + } + } + } + + JSONObject result = this.getCoordinateGis(coord, depth); + + address += result.get("add"); + + result.put("address", address); + + return result; + + } catch (Exception e) { + e.printStackTrace(); + } + + + return null; // 모든 작업이 실패한 경우 null 반환 + + } + + public JSONObject getCoordinateGis(Coordinate coordinate, JSONObject polygon) throws IOException, ParseException { + + JSONObject obj = new JSONObject(); + + obj = parseGeoJson(polygon, coordinate); + + if(obj == null) return null; + + return obj; + + } + + public JSONObject getCoordinateGis(Coordinate coordinate, String depth) throws IOException, ParseException { + + JSONObject obj = new JSONObject(); + + String address = ""; + + String path = basePath + depth.substring(0,2) + "/" + depth + "/"; + + while(true) { + + File file = new File(path+baseFileName); + + if(!file.exists()) { + + obj.put("add", address); + + return obj; + } + + obj = parseGeoJson(path+baseFileName, coordinate); + + if(obj == null) return null; + + address += " " + obj.get("KOR_NM"); + + path += obj.get("CD")+"/"; + + } + } + + public JSONObject parseGeoJson(JSONObject obj, Coordinate coordinate) throws IOException, ParseException { + + Point point = geometryFactory.createPoint(coordinate); + String type = (String) obj.get("type"); + + List features = (List) obj.get("features"); + + return this.contains(features, point); + + } + + public JSONObject parseGeoJson(String path, Coordinate coordinate) throws IOException, ParseException { + + List features = new ArrayList(); + + Point point = null; + + try(InputStream inputStream = new FileInputStream(path); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8192)) { + + JSONParser jsonParser = new JSONParser(); + + JSONObject jsonObject = (JSONObject) jsonParser.parse(reader); + + + point = geometryFactory.createPoint(coordinate); + + features = (List) jsonObject.get("features"); + + }catch(Exception e) { + + e.getStackTrace(); + + } + + + return this.contains(features, point); + + } + + + + public JSONObject contains(List features, Point point) { + + JSONObject result = null; + + Double standard = 10000000.0; + + for(int i=0; i coordinates = (List) geometry.get("coordinates"); + + for(int k = 0; k< coordinates.size(); k++) { + + List polygonPaths = new ArrayList<>(); + + for(Object coords : coordinates.get(k)) { + + for(int j = 0; j<((JSONArray)coords).size(); j++) { + + Object coord = ((JSONArray) coords).get(j); + + Object x = ((JSONArray) coord).get(0); + Object y = ((JSONArray) coord).get(1); + + Double lon = y instanceof Double ? (Double) y : Double.valueOf((Long) y); + Double lat = x instanceof Double ? (Double) x : Double.valueOf((Long) x); + + Coordinate areaCoord = new Coordinate(lon, lat); + + polygonPaths.add(areaCoord); + + } + + polygonPaths.add(polygonPaths.get(0)); + + } + + Polygon polygon = geometryFactory.createPolygon(polygonPaths.toArray(new Coordinate[] {})); + + if(polygon.contains(point)) { + + return properties; + + }else { + + Double distance = polygon.distance(point); + + if(standard > distance) { + + standard = distance; + + result = properties; + } + } + } + } + + result.put("distance", standard); + + return result; + + } +} diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltCptAuthAdmDistrictBasQueryRepository.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltCptAuthAdmDistrictBasQueryRepository.java new file mode 100644 index 0000000..7e6387a --- /dev/null +++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltCptAuthAdmDistrictBasQueryRepository.java @@ -0,0 +1,40 @@ +package kr.co.palnet.kac.data.flt.repository; + +import com.querydsl.core.BooleanBuilder; +import com.querydsl.jpa.impl.JPAQueryFactory; +import kr.co.palnet.kac.data.flt.model.FltCptAuthBas; +import kr.co.palnet.kac.data.flt.model.QFltCptAuthAdmDistrictRel; +import kr.co.palnet.kac.data.flt.model.QFltCptAuthBas; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +@RequiredArgsConstructor +public class FltCptAuthAdmDistrictBasQueryRepository { + + private final JPAQueryFactory query; + + public List geFltCptAuthBas(String cd){ + + QFltCptAuthAdmDistrictRel qFltCptAuthAdmDistrictRel = QFltCptAuthAdmDistrictRel.fltCptAuthAdmDistrictRel; + QFltCptAuthBas qFltCptAuthBas = QFltCptAuthBas.fltCptAuthBas; + + BooleanBuilder builder = new BooleanBuilder(); + builder.and(qFltCptAuthAdmDistrictRel.ADM_CD.like(cd+"%")); + + List result = query + .selectDistinct( + qFltCptAuthBas + ) + .from(qFltCptAuthAdmDistrictRel) + .leftJoin(qFltCptAuthBas) + .on(qFltCptAuthAdmDistrictRel.CPT_AUTH_CODE.eq(qFltCptAuthBas.cptAuthCode)) + .where(builder) + .fetch(); + + + return result; + } +} diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/service/FltCptAuthDomainService.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/service/FltCptAuthDomainService.java new file mode 100644 index 0000000..1b22670 --- /dev/null +++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/service/FltCptAuthDomainService.java @@ -0,0 +1,18 @@ +package kr.co.palnet.kac.data.flt.service; + +import kr.co.palnet.kac.data.flt.model.FltCptAuthBas; +import kr.co.palnet.kac.data.flt.repository.FltCptAuthAdmDistrictBasQueryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class FltCptAuthDomainService { + + private final FltCptAuthAdmDistrictBasQueryRepository fltCptAuthAdmDistrictBasQueryRepository; + public List getFltCptAuthBas(String cdParam){ + return fltCptAuthAdmDistrictBasQueryRepository.geFltCptAuthBas(cdParam); + } +} diff --git a/web/api-common/build.gradle b/web/api-common/build.gradle index 38bf4c1..288773d 100644 --- a/web/api-common/build.gradle +++ b/web/api-common/build.gradle @@ -3,12 +3,14 @@ dependencies { implementation "$boot:spring-boot-starter-web" implementation "$boot:spring-boot-starter-data-jpa" + implementation 'com.googlecode.json-simple:json-simple:1.1.1' // for paging // implementation("org.springframework.data:spring-data-commons") compileOnly 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0' compileOnly 'org.locationtech.jts:jts-core:1.19.0' implementation project(":data:com") + implementation project(":data:flt") implementation project(":common:core") compileOnly project(":common:util") compileOnly project(":web:security") diff --git a/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/controller/ComCoordinateController.java b/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/controller/ComCoordinateController.java new file mode 100644 index 0000000..62e898b --- /dev/null +++ b/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/controller/ComCoordinateController.java @@ -0,0 +1,61 @@ +package kr.co.palnet.kac.api.v1.common.coordinate.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import kr.co.palnet.kac.api.v1.common.coordinate.model.CompotentAuthorityRQ; +import kr.co.palnet.kac.api.v1.common.coordinate.model.CompotentAuthorityRS; +import kr.co.palnet.kac.api.v1.common.coordinate.service.ComCoordinateService; +import kr.co.palnet.kac.core.exception.BaseException; +import kr.co.palnet.kac.core.response.BasicResponse; +import kr.co.palnet.kac.core.response.ErrorResponse; +import kr.co.palnet.kac.core.response.SuccessResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/v1/com/coordinate") +@Slf4j +@Tag(name = "공통 API", description = "공통 API") +public class ComCoordinateController { + + private final ComCoordinateService comCoordinateService; + + /** + * 좌표로 관할기관 가져오기 + * @param rq + * @return + */ + @Operation(summary = "좌표로 관할 기관청 가져오기", description = "좌표로 관할 기관청 가져오기") + @GetMapping("/comptent-authority") + public ResponseEntity getCompetentAuthority(CompotentAuthorityRQ rq){ + + CompotentAuthorityRS result = new CompotentAuthorityRS(); + + try { + result = comCoordinateService.getCompetentAuthority(rq); + } catch (BaseException e) { + Map resultMap = new HashMap<>(); + log.error("IGNORE : ", e); + resultMap.put("result", false); + resultMap.put("errorCode", e.getErrorCode()); + resultMap.put("errorMessage", e.getMessage()); + return ResponseEntity.ok().body(new SuccessResponse<>(resultMap)); + } catch (Exception e) { + log.error("IGNORE : ", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ErrorResponse("Server Error", "-1")); + + } + + return ResponseEntity.ok().body(new SuccessResponse<>(result)); + } +} diff --git a/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/model/CompotentAuthorityRQ.java b/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/model/CompotentAuthorityRQ.java new file mode 100644 index 0000000..56f1c2f --- /dev/null +++ b/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/model/CompotentAuthorityRQ.java @@ -0,0 +1,12 @@ +package kr.co.palnet.kac.api.v1.common.coordinate.model; + +import lombok.Data; + +@Data +public class CompotentAuthorityRQ { + + private Double lat; + + private Double lon; + +} diff --git a/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/model/CompotentAuthorityRS.java b/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/model/CompotentAuthorityRS.java new file mode 100644 index 0000000..986dea1 --- /dev/null +++ b/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/model/CompotentAuthorityRS.java @@ -0,0 +1,17 @@ +package kr.co.palnet.kac.api.v1.common.coordinate.model; + +import kr.co.palnet.kac.data.flt.model.FltCptAuthBas; +import lombok.Data; + +import java.util.List; + +@Data +public class CompotentAuthorityRS { + + private String DMS; + + private String address; + + private List fltCptpAuthBasList; + +} diff --git a/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/service/ComCoordinateService.java b/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/service/ComCoordinateService.java new file mode 100644 index 0000000..b92f739 --- /dev/null +++ b/web/api-common/src/main/java/kr/co/palnet/kac/api/v1/common/coordinate/service/ComCoordinateService.java @@ -0,0 +1,111 @@ +package kr.co.palnet.kac.api.v1.common.coordinate.service; + + +import kr.co.palnet.kac.api.v1.common.coordinate.model.CompotentAuthorityRQ; +import kr.co.palnet.kac.api.v1.common.coordinate.model.CompotentAuthorityRS; +import kr.co.palnet.kac.data.flt.model.FltCptAuthBas; +import kr.co.palnet.kac.data.flt.service.FltCptAuthDomainService; +import kr.co.palnet.kac.util.DmsUtils; +import kr.co.palnet.kac.util.kisa.CoordUtils; +import lombok.RequiredArgsConstructor; +import org.json.simple.JSONObject; +import org.json.simple.parser.ParseException; +import org.locationtech.jts.geom.Coordinate; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Service +@RequiredArgsConstructor +public class ComCoordinateService { + + private final FltCptAuthDomainService fltCptAuthDomainService; + public CompotentAuthorityRS getCompetentAuthority(CompotentAuthorityRQ rq){ + + Coordinate coord = new Coordinate(rq.getLat(), rq.getLon()); + + CoordUtils utils = CoordUtils.getInstance(); + + String dms = DmsUtils.convertDDtoDMS(coord); + + JSONObject code = new JSONObject(); + try { + code = utils.getPlace(coord); + } catch (ParseException e) { + e.printStackTrace(); + } catch (IOException e){ + e.printStackTrace(); + } catch (Exception e){ + e.printStackTrace(); + } + + String[] scope = {"ctprvn", "sig", "emd", "li"}; + final String cd = (String) code.get("CD"); + + Set fltCptAuthBas = new HashSet(); + + for(int i = 0; i < scope.length; i++){ + String cdParam = this.codeParsing(cd, scope[i]); + List authList = fltCptAuthDomainService.getFltCptAuthBas(cdParam); + + fltCptAuthBas.addAll(new HashSet(authList)); + } + + CompotentAuthorityRS result = new CompotentAuthorityRS(); + + result.setFltCptpAuthBasList(new ArrayList<>(fltCptAuthBas)); + result.setDMS(dms); + result.setAddress(code.get("address").toString()); + + return result; + } + + private String codeParsing(String cd, String scope){ + switch (scope) { + case "ctprvn": + + if(cd.length() < 2) break; + + cd = cd.substring(0, 2); + break; + case "sig": + + if(cd.length() < 5) break; + + cd = cd.substring(0, 5); + break; + case "emd": + + if(cd.length() < 8) break; + + cd = cd.substring(0, 8); + break; + case "li": + + if(cd.length() < 10) break; + + cd = cd.substring(0, 10); + break; + } + + int length = cd.length(); + int maxLength = 10; + + int difference = maxLength - length; + + StringBuilder sb = new StringBuilder(); + sb.append(cd); + + for(int i = 0; i < difference; i++){ + sb.append("0"); + } + + return sb.toString(); + } + +} +