Innopam -> gukyuin 이름 변경
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
package com.kamco.cd.kamcoback.gukyuin;
|
||||
|
||||
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
|
||||
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto;
|
||||
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ChnDetectMastReqDto;
|
||||
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ChngDetectMastSearchDto;
|
||||
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ResReturn;
|
||||
import com.kamco.cd.kamcoback.gukyuin.dto.DetectMastDto.Basic;
|
||||
import com.kamco.cd.kamcoback.gukyuin.dto.DetectMastDto.DetectMastReq;
|
||||
import com.kamco.cd.kamcoback.gukyuin.service.GukYuinApiService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "국유인 연동 API", description = "국유인 연동 API")
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/gukyuin/")
|
||||
public class GukYuinApiController {
|
||||
|
||||
private final GukYuinApiService gukYuinApiService;
|
||||
|
||||
/** 탐지결과 등록 */
|
||||
@Operation(summary = "탐지결과 등록", description = "탐지결과 등록")
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
responseCode = "201",
|
||||
description = "등록 성공",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = DetectMastReq.class))),
|
||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||
})
|
||||
@PostMapping("/mast/regist")
|
||||
public ChngDetectMastDto.Basic regist(
|
||||
@RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) {
|
||||
return gukYuinApiService.regist(chnDetectMastReq);
|
||||
}
|
||||
|
||||
@Operation(summary = "탐지결과 삭제", description = "탐지결과 삭제")
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
responseCode = "201",
|
||||
description = "등록 성공",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = ChnDetectMastReqDto.class))),
|
||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||
})
|
||||
@PostMapping("/mast/remove")
|
||||
public ResReturn remove(
|
||||
@RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) {
|
||||
return gukYuinApiService.remove(chnDetectMastReq);
|
||||
}
|
||||
|
||||
@Operation(summary = "탐지결과 등록목록 조회", description = "탐지결과 등록목록 조회")
|
||||
@GetMapping("/mast/list")
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "목록 성공",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = Basic.class))),
|
||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||
})
|
||||
public List<ChngDetectMastDto.Basic> selectChangeDetectionList(
|
||||
@RequestParam(required = false) String chnDtctId,
|
||||
@RequestParam(required = false) String cprsYr,
|
||||
@RequestParam(required = false) String crtrYr,
|
||||
@RequestParam(required = false) String chnDtctSno) {
|
||||
ChngDetectMastSearchDto searchDto = new ChngDetectMastSearchDto();
|
||||
searchDto.setChnDtctId(chnDtctId);
|
||||
searchDto.setCprsYr(cprsYr);
|
||||
searchDto.setCrtrYr(crtrYr);
|
||||
searchDto.setChnDtctSno(chnDtctSno);
|
||||
return gukYuinApiService.list(searchDto);
|
||||
}
|
||||
|
||||
public ApiResponseDto<Boolean> getIsLinkGukYuin(UUID uuid) {
|
||||
gukYuinApiService.getIsLinkGukYuin(uuid);
|
||||
return ApiResponseDto.ok(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.kamco.cd.kamcoback.gukyuin.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
public class ChngDetectMastDto {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Basic {
|
||||
|
||||
private String chnDtctMstId; // 탐지마스터아이디
|
||||
private String cprsYr; // 비교년도 2023
|
||||
private String crtrYr; // 기준년도 2024
|
||||
private String chnDtctSno; // 차수 (1 | 2 | ...)
|
||||
private String chnDtctId; // 탐지아이디. UUID를 기반으로 '-'를 제거하고 대문자/숫자로 구성
|
||||
private String chnDtctCnt; // 탐지객체개수
|
||||
private String pnuMpngCnt; // PNU매핑개수
|
||||
private String lrmYmd; // 지적도일자
|
||||
private String pathNm; // 탐지결과 절대경로명 /kamco_nas/export/{chnDtctId}
|
||||
private List<ChnDetectMastExcnStepDto> excnList; // 등록진행상태히스토리 (최근것부터 DESC)
|
||||
private String excnStepCd; // 실행단계코드
|
||||
private String excnStep; // 실행단계코드에 해당하는 영문명
|
||||
private String excnPgrt; // 실행단계진행율
|
||||
private String excnBngnDt; // 실행단계시작시간
|
||||
private String excnEndDt; // 실행단계종료시간
|
||||
private String rmk; // 비고
|
||||
private String crtDt; // 생성일시
|
||||
private String crtEpno; // 생성사원번호
|
||||
private String crtIp; // 생성사원아이피
|
||||
private String chgDt; // 변경일시
|
||||
private String chgEpno; // 변경사원번호
|
||||
private String chgIp; // 변경사원아이피
|
||||
private String delYn; // 삭제여부
|
||||
//
|
||||
private String reqEpno; // 요청사원번호
|
||||
private String reqIp; // 요청사원어이피
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class ChnDetectMastExcnStepDto {
|
||||
|
||||
private String srno; // 일련번호
|
||||
private String chnDtctMstId; // 탐지마스터아이디
|
||||
private String excnStepCd; // 실행단계코드
|
||||
private String excnStep; // 실행단계코드에 해당하는 영문명
|
||||
private String excnPgrt; // 실행단계진행율
|
||||
private String excnEndDt; // 실행단계종료시간
|
||||
private String errCd; // 오류코드
|
||||
private String errMsg; // 오류메세지
|
||||
private String crtDt; // 실행단계시작시간
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class ChnDetectMastReqDto {
|
||||
|
||||
private String cprsYr; // 비교년도 2023
|
||||
private String crtrYr; // 기준년도 2024
|
||||
private String chnDtctSno; // 차수 (1 | 2 | ...)
|
||||
private String chnDtctId; // 탐지아이디. UUID를 기반으로 '-'를 제거하고 대문자/숫자로 구성
|
||||
private String pathNm; // 탐지결과 절대경로명 /kamco_nas/export/{chnDtctId}
|
||||
private String reqEpno; // 사원번호
|
||||
private String reqIp; // 사원아이피
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class ChnDetectContDto {
|
||||
|
||||
private String chnDtctMstId; // 탐지콘텐츠아이디
|
||||
private String chnDtctContId; // 탐지마스타아이디
|
||||
private String cprsYr; // 비교년도 2023
|
||||
private String crtrYr; // 기준년도 2024
|
||||
private String chnDtctSno; // 차수 (1 | 2 | ...)
|
||||
private String mpqdNo; // 도엽번호
|
||||
private String chnDtctId; // 탐지아이디. UUID를 기반으로 '-'를 제거하고 대문자/숫자로 구성
|
||||
private String chnDtctObjtId; // 탐지객체아이디. UUID를 기반으로 '-'를 제거하고 대문자/숫자로 구성
|
||||
private String chnDtctPolygon; // 탐지객체폴리곤
|
||||
private String chnDtctSqms; // 탐지객체면적
|
||||
private String chnCd; // 변화코드
|
||||
private String chnDtctJson; // 변화탐지JSON
|
||||
private String chnDtctProb; // 변화탐지정확도
|
||||
private String bfClsCd; // 이전부류코드
|
||||
private String bfClsProb; // 이전분류정확도
|
||||
private String afClsCd; // 이후분류코드
|
||||
private String afClsProb; // 이후분류정확도
|
||||
private String crtDt; // 생성일시
|
||||
private String crtEpno; // 생성사원번호
|
||||
private String crtIp; // 생성사원아이피
|
||||
private String delYn; // 삭제여부
|
||||
//
|
||||
private String reqEpno; // 요청사원번호
|
||||
private String reqIp; // 요청사원아이피
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class ChnDetectContReqDto {
|
||||
|
||||
private String cprsYr; // 비교년도 2023
|
||||
private String crtrYr; // 기준년도 2024
|
||||
private String chnDtctSno; // 차수 (1 | 2 | ...)
|
||||
private String mpqdNo; // 도엽번호
|
||||
private String chnDtctId; // 탐지아이디. UUID를 기반으로 '-'를 제거하고 대문자/숫자로 구성
|
||||
private String chnDtctObjtId; // 탐지객체아이디. UUID를 기반으로 '-'를 제거하고 대문자/숫자로 구성
|
||||
private String reqEpno; // 사원번호
|
||||
private String reqIp;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class ChngDetectMastSearchDto {
|
||||
|
||||
private String chnDtctId;
|
||||
private String cprsYr;
|
||||
private String crtrYr;
|
||||
private String chnDtctSno;
|
||||
}
|
||||
|
||||
@Schema(name = "ResReturn", description = "수행 후 리턴")
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class ResReturn {
|
||||
|
||||
private String flag;
|
||||
private String message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.kamco.cd.kamcoback.gukyuin.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
public class DetectMastDto {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Basic {
|
||||
|
||||
private Long dtctMstId;
|
||||
private String cprsBfYr;
|
||||
private String cprsAdYr;
|
||||
private Integer dtctSno;
|
||||
private String pathNm;
|
||||
private String crtEpno;
|
||||
private String crtIp;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class DetectMastReq {
|
||||
|
||||
@NotBlank
|
||||
@Schema(description = "before 연도", example = "2023")
|
||||
private String cprsBfYr;
|
||||
|
||||
@NotBlank
|
||||
@Schema(description = "after 연도", example = "2024")
|
||||
private String cprsAdYr;
|
||||
|
||||
@NotNull
|
||||
@Schema(description = "차수(회차)", example = "4")
|
||||
private Integer dtctSno;
|
||||
|
||||
@NotBlank
|
||||
@Schema(description = "파일경로", example = "/app/detect/result/2023_2024/4")
|
||||
private String pathNm;
|
||||
|
||||
@NotBlank
|
||||
@Schema(description = "사원번호", example = "1234567")
|
||||
private String crtEpno;
|
||||
|
||||
@NotBlank
|
||||
@Schema(description = "아이피", example = "0.0.0.0")
|
||||
private String crtIp;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class DetectMastSearch {
|
||||
|
||||
private String cprsBfYr;
|
||||
private String cprsAdYr;
|
||||
private Integer dtctSno;
|
||||
private String featureId;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class FeaturePnuDto {
|
||||
|
||||
private String featureId; // polygon_id
|
||||
private String pnu; // 랜덤 생성
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.kamco.cd.kamcoback.gukyuin.service;
|
||||
|
||||
import com.kamco.cd.kamcoback.common.utils.NetUtils;
|
||||
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient;
|
||||
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult;
|
||||
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto;
|
||||
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ResReturn;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@Transactional(readOnly = true)
|
||||
@RequiredArgsConstructor
|
||||
public class GukYuinApiService {
|
||||
|
||||
@Value("${spring.profiles.active:local}")
|
||||
private String profile;
|
||||
|
||||
@Value("${gukyuin.url}")
|
||||
private String gukyuinUrl;
|
||||
|
||||
@Value("${gukyuin.mast}")
|
||||
private String gukyuinMastUrl;
|
||||
|
||||
private final ExternalHttpClient externalHttpClient;
|
||||
private final NetUtils netUtils = new NetUtils();
|
||||
|
||||
@Transactional
|
||||
public ChngDetectMastDto.Basic regist(ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) {
|
||||
|
||||
ChngDetectMastDto.Basic basic = new ChngDetectMastDto.Basic();
|
||||
|
||||
String url = gukyuinMastUrl + "/regist";
|
||||
// url = "http://localhost:8080/api/kcd/cdi/detect/mast/regist";
|
||||
|
||||
String myip = netUtils.getLocalIP();
|
||||
chnDetectMastReq.setReqIp(myip);
|
||||
|
||||
System.out.println("url == " + url);
|
||||
System.out.println("url == " + myip);
|
||||
|
||||
ExternalCallResult<String> result =
|
||||
externalHttpClient.call(
|
||||
url, HttpMethod.POST, chnDetectMastReq, netUtils.jsonHeaders(), String.class);
|
||||
|
||||
System.out.println("result == " + result);
|
||||
|
||||
return basic;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public ResReturn remove(ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) {
|
||||
ChngDetectMastDto.Basic basic = new ChngDetectMastDto.Basic();
|
||||
|
||||
String url = gukyuinMastUrl + "/remove";
|
||||
// url = "http://localhost:8080/api/kcd/cdi/detect/mast/remove";
|
||||
|
||||
String myip = netUtils.getLocalIP();
|
||||
chnDetectMastReq.setReqIp(myip);
|
||||
|
||||
System.out.println("url == " + url);
|
||||
System.out.println("url == " + myip);
|
||||
|
||||
ExternalCallResult<String> result =
|
||||
externalHttpClient.call(
|
||||
url, HttpMethod.POST, chnDetectMastReq, netUtils.jsonHeaders(), String.class);
|
||||
|
||||
System.out.println("result == " + result);
|
||||
|
||||
return new ResReturn("success", "탐지결과 삭제 되었습니다.");
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<ChngDetectMastDto.Basic> list(ChngDetectMastDto.ChngDetectMastSearchDto searchDto) {
|
||||
List<ChngDetectMastDto.Basic> masterList = new ArrayList<>();
|
||||
|
||||
String queryString = netUtils.dtoToQueryString(searchDto, null);
|
||||
String url = gukyuinMastUrl + queryString;
|
||||
|
||||
ExternalCallResult<String> result =
|
||||
externalHttpClient.call(url, HttpMethod.GET, null, netUtils.jsonHeaders(), String.class);
|
||||
|
||||
System.out.println("list result == " + result);
|
||||
|
||||
return masterList;
|
||||
}
|
||||
|
||||
public Boolean getIsLinkGukYuin(UUID uuid) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.kamco.cd.kamcoback.gukyuin.utils;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.GeometryFactory;
|
||||
import org.locationtech.jts.geom.LinearRing;
|
||||
import org.locationtech.jts.geom.MultiPolygon;
|
||||
import org.locationtech.jts.geom.Polygon;
|
||||
|
||||
public class GeoJsonGeometryConverter {
|
||||
|
||||
private static final GeometryFactory GF = new GeometryFactory();
|
||||
|
||||
public static Geometry toGeometry(JsonNode geomNode) {
|
||||
String type = geomNode.path("type").asText();
|
||||
|
||||
if ("Polygon".equals(type)) {
|
||||
return toPolygon(geomNode.path("coordinates"));
|
||||
}
|
||||
if ("MultiPolygon".equals(type)) {
|
||||
return toMultiPolygon(geomNode.path("coordinates"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Polygon toPolygon(JsonNode coords) {
|
||||
LinearRing shell = GF.createLinearRing(toCoords(coords.get(0)));
|
||||
return GF.createPolygon(shell);
|
||||
}
|
||||
|
||||
private static MultiPolygon toMultiPolygon(JsonNode coords) {
|
||||
Polygon[] polys = new Polygon[coords.size()];
|
||||
for (int i = 0; i < coords.size(); i++) {
|
||||
polys[i] = toPolygon(coords.get(i));
|
||||
}
|
||||
return GF.createMultiPolygon(polys);
|
||||
}
|
||||
|
||||
private static Coordinate[] toCoords(JsonNode ring) {
|
||||
Coordinate[] c = new Coordinate[ring.size() + 1];
|
||||
for (int i = 0; i < ring.size(); i++) {
|
||||
c[i] = new Coordinate(ring.get(i).get(0).asDouble(), ring.get(i).get(1).asDouble());
|
||||
}
|
||||
c[c.length - 1] = c[0];
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.kamco.cd.kamcoback.gukyuin.utils;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GeoJsonLoader {
|
||||
|
||||
private final ObjectMapper om = new ObjectMapper();
|
||||
|
||||
public GeoJsonFile load(File geoJsonFile) throws Exception {
|
||||
|
||||
JsonNode root = om.readTree(geoJsonFile);
|
||||
|
||||
long mapId = root.path("properties").path("map_id").asLong(-1);
|
||||
if (mapId <= 0) {
|
||||
throw new IllegalStateException(
|
||||
"GeoJSON top-level properties.map_id 없음: " + geoJsonFile.getName());
|
||||
}
|
||||
|
||||
List<JsonNode> features = new ArrayList<>();
|
||||
root.path("features").forEach(features::add);
|
||||
|
||||
return new GeoJsonFile(mapId, features);
|
||||
}
|
||||
|
||||
/** ✅ feature에서 polygon_id 추출 */
|
||||
public static String polygonId(JsonNode feature) {
|
||||
return feature.path("properties").path("polygon_id").asText(null);
|
||||
}
|
||||
|
||||
public static class GeoJsonFile {
|
||||
|
||||
public final long mapId;
|
||||
public final List<JsonNode> features;
|
||||
|
||||
public GeoJsonFile(long mapId, List<JsonNode> features) {
|
||||
this.mapId = mapId;
|
||||
this.features = features;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.kamco.cd.kamcoback.gukyuin.utils;
|
||||
|
||||
public class MapIdUtils {
|
||||
|
||||
private MapIdUtils() {
|
||||
// util class
|
||||
}
|
||||
|
||||
/** map_id → 시도코드 예: 34602060 → "34" */
|
||||
public static String sidoCodeFromMapId(long mapId) {
|
||||
String s = String.valueOf(mapId);
|
||||
if (s.length() < 2) {
|
||||
throw new IllegalArgumentException("잘못된 map_id: " + mapId);
|
||||
}
|
||||
return s.substring(0, 2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.kamco.cd.kamcoback.gukyuin.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.geotools.api.data.DataStore;
|
||||
import org.geotools.api.data.DataStoreFinder;
|
||||
import org.geotools.api.data.SimpleFeatureSource;
|
||||
import org.geotools.api.feature.simple.SimpleFeature;
|
||||
import org.geotools.data.simple.SimpleFeatureCollection;
|
||||
import org.geotools.data.simple.SimpleFeatureIterator;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.index.strtree.STRtree;
|
||||
|
||||
public class ShpIndexManager {
|
||||
|
||||
private static final String SHP_ROOT = "/shp";
|
||||
private static final String SHP_YYYYMM = "202512";
|
||||
private static final String PNU_FIELD = "PNU";
|
||||
|
||||
private final Map<String, STRtree> cache = new ConcurrentHashMap<>();
|
||||
|
||||
public STRtree getIndex(String sidoCode) {
|
||||
return cache.computeIfAbsent(sidoCode, this::loadIndex);
|
||||
}
|
||||
|
||||
private STRtree loadIndex(String sidoCode) {
|
||||
try {
|
||||
String path = SHP_ROOT + "/LSMD_CONT_LDREG_" + sidoCode + "_" + SHP_YYYYMM + ".shp";
|
||||
|
||||
File shp = new File(path);
|
||||
if (!shp.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
STRtree index = new STRtree(10);
|
||||
|
||||
DataStore store = DataStoreFinder.getDataStore(Map.of("url", shp.toURI().toURL()));
|
||||
|
||||
String typeName = store.getTypeNames()[0];
|
||||
SimpleFeatureSource source = store.getFeatureSource(typeName);
|
||||
SimpleFeatureCollection col = source.getFeatures();
|
||||
|
||||
try (SimpleFeatureIterator it = col.features()) {
|
||||
while (it.hasNext()) {
|
||||
SimpleFeature f = it.next();
|
||||
Geometry geom = (Geometry) f.getDefaultGeometry();
|
||||
String pnu = Objects.toString(f.getAttribute(PNU_FIELD), null);
|
||||
if (geom != null && pnu != null) {
|
||||
index.insert(geom.getEnvelopeInternal(), new ShpRow(geom, pnu));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index.build();
|
||||
store.dispose();
|
||||
return index;
|
||||
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** SHP 한 row */
|
||||
public static class ShpRow {
|
||||
|
||||
public final Geometry geom;
|
||||
public final String pnu;
|
||||
|
||||
public ShpRow(Geometry geom, String pnu) {
|
||||
this.geom = geom;
|
||||
this.pnu = pnu;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.kamco.cd.kamcoback.gukyuin.utils;
|
||||
|
||||
import java.util.List;
|
||||
import org.locationtech.jts.geom.Envelope;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.prep.PreparedGeometry;
|
||||
import org.locationtech.jts.geom.prep.PreparedGeometryFactory;
|
||||
import org.locationtech.jts.index.strtree.STRtree;
|
||||
|
||||
public class ShpPnuMatcher {
|
||||
|
||||
public static String pickByIntersectionMax(STRtree index, Geometry target) {
|
||||
|
||||
Envelope env = target.getEnvelopeInternal();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ShpIndexManager.ShpRow> rows = index.query(env);
|
||||
|
||||
double best = 0;
|
||||
String bestPnu = null;
|
||||
|
||||
for (ShpIndexManager.ShpRow row : rows) {
|
||||
|
||||
PreparedGeometry prep = PreparedGeometryFactory.prepare(row.geom);
|
||||
|
||||
if (prep.contains(target) || prep.covers(target)) {
|
||||
return row.pnu;
|
||||
}
|
||||
|
||||
if (!prep.intersects(target)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double area = row.geom.intersection(target).getArea();
|
||||
if (area > best) {
|
||||
best = area;
|
||||
bestPnu = row.pnu;
|
||||
}
|
||||
}
|
||||
return bestPnu;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user