diff --git a/src/main/java/geoinfo/com/WebConfirm.java b/src/main/java/geoinfo/com/WebConfirm.java index b09ed5e3..aa86035c 100644 --- a/src/main/java/geoinfo/com/WebConfirm.java +++ b/src/main/java/geoinfo/com/WebConfirm.java @@ -8,6 +8,7 @@ import java.util.*; import javax.servlet.http.HttpServletRequest; +import org.hsqldb.result.Result; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,12 +31,179 @@ public class WebConfirm String user = EgovProperties.getProperty("Oracle.ID").trim(); String pw = EgovProperties.getProperty("Oracle.Password").trim(); + + /** + * TEMP_SPT 테이블의 표준관입시험 심도 중복을 검사합니다. + * 중복 건이 발견되면 에러 메시지를 포함한 Map을 반환합니다. + * + * @param request HttpServletRequest + * @param PROJECT_CODE 검사할 프로젝트 코드 + * @return 유효성 검사 결과 (success: true/false, errorMessage: "...") + */ + private Map validationCheckTempSpt(HttpServletRequest request, final String PROJECT_CODE) { + Map result = new HashMap<>(); + DatabaseQuery validationQuery = null; + ResultSet rs = null; + + // 사용자가 요청한 중복 검사 SQL + final String validationSql = "SELECT " + + " HOLE_CODE, " + + " DEPTH_SPT, " + + " COUNT(1) AS \"COUNT\" " + + "FROM " + + " TEMP_SPT " + + "WHERE " + + " PROJECT_CODE = [PROJECT_CODE] " + + "GROUP BY " + + " HOLE_CODE, " + + " DEPTH_SPT " + + "HAVING " + + " 1 < COUNT(1)"; + + try { + validationQuery = new DatabaseQuery(validationSql); + validationQuery.setParam("PROJECT_CODE", PROJECT_CODE); + + // 클래스 멤버 변수인 connection 사용 + rs = validationQuery.execute(connection); + + StringBuilder errorMessages = new StringBuilder(); + + // 발견된 모든 중복 건에 대한 에러 메시지를 생성 + while (rs.next()) { + String holeCode = rs.getString("HOLE_CODE"); + String depthSpt = rs.getString("DEPTH_SPT"); + int count = rs.getInt("COUNT"); + + // 여러 건의 에러 메시지를 하나로 합침 + errorMessages.append("- " + holeCode + " 시추공의 심도 " + depthSpt + "m가 " + count + "개 중복됨.\\n"); + } + + // 중복(에러)이 발견되었는지 확인 + if (errorMessages.length() > 0) { + result.put("success", false); + result.put("errorMessage", errorMessages.toString().trim()); + } else { + // 중복 없음, 유효성 검사 통과 + result.put("success", true); + result.put("errorMessage", ""); + } + + } catch (SQLException e) { + // SQL 실행 중 예외 발생 + logger.error("SPT validation check error", e); // 클래스 멤버 logger 사용 + result.put("success", false); + result.put("errorMessage", "표준관입시험 유효성 검사 중 데이터베이스 오류가 발생했습니다: " + e.getMessage()); + } finally { + // 리소스 정리 (ConfirmProject의 finally 블록과 유사하게) + try { + if (rs != null) { + rs.close(); + } + if (validationQuery != null) { + validationQuery.close(); + } + } catch (SQLException sqle) { + logger.error("Error closing validation resources", sqle); + } + } + + return result; + } + + + /** + * TEMP_FIELDPER_SUB 테이블의 현장투수시험 '경과시간(sec)' 중복을 검사합니다. + * 중복 건이 발견되면 에러 메시지를 포함한 Map을 반환합니다. + * + * @param request HttpServletRequest + * @param PROJECT_CODE 검사할 프로젝트 코드 + * @return 유효성 검사 결과 (success: true/false, errorMessage: "...") + */ + private Map validationCheckTempFieldperSub(HttpServletRequest request, final String PROJECT_CODE) { + Map result = new HashMap<>(); + DatabaseQuery validationQuery = null; + ResultSet rs = null; + + // 사용자가 요청한 중복 검사 SQL + final String validationSql = "SELECT " + + " HOLE_CODE, " + + " FIELDPER_CODE, " + + " FIELDPER_SUB_TIME, " + + " COUNT(1) AS \"COUNT\" " + + "FROM " + + " TEMP_FIELDPER_SUB " + + "WHERE " + + " PROJECT_CODE = [PROJECT_CODE] " + + "GROUP BY " + + " HOLE_CODE, " + + " FIELDPER_CODE, " + + " FIELDPER_SUB_TIME " + + "HAVING " + + " 1 < COUNT(1)"; + + + try { + validationQuery = new DatabaseQuery(validationSql); + validationQuery.setParam("PROJECT_CODE", PROJECT_CODE); + + // 클래스 멤버 변수인 connection 사용 + rs = validationQuery.execute(connection); + + StringBuilder errorMessages = new StringBuilder(); + + // 발견된 모든 중복 건에 대한 에러 메시지를 생성 + while (rs.next()) { + String holeCode = rs.getString("HOLE_CODE"); + String fieldperCode = rs.getString("FIELDPER_CODE"); + String fieldperSubTime = rs.getString("FIELDPER_SUB_TIME"); + int count = rs.getInt("COUNT"); + + // 여러 건의 에러 메시지를 하나로 합침 + errorMessages.append("- " + holeCode + " 시추공 시험코드[" + fieldperCode + "]의 시간간격(sec) " + fieldperSubTime + "sec가 " + count + "개 중복됨.\\n"); + } + + // 중복(에러)이 발견되었는지 확인 + if (errorMessages.length() > 0) { + result.put("success", false); + result.put("errorMessage", errorMessages.toString().trim()); + } else { + // 중복 없음, 유효성 검사 통과 + result.put("success", true); + result.put("errorMessage", ""); + } + + } catch (SQLException e) { + // SQL 실행 중 예외 발생 + logger.error("SPT validation check error", e); // 클래스 멤버 logger 사용 + result.put("success", false); + result.put("errorMessage", "현장투수시험 유효성 검사 중 데이터베이스 오류가 발생했습니다: " + e.getMessage()); + } finally { + // 리소스 정리 (ConfirmProject의 finally 블록과 유사하게) + try { + if (rs != null) { + rs.close(); + } + if (validationQuery != null) { + validationQuery.close(); + } + } catch (SQLException sqle) { + logger.error("Error closing validation resources", sqle); + } + } + + return result; + } + + + + /* * public WebConfirm() { this.connection = null; this.connectionPool = null; * this.query = null; this.resultSet = null; this.sql = ""; this.resultCnt = 0; * this.resultBool = false; } */ - public boolean ConfirmProject(HttpServletRequest request, final String PROJECT_CODE) { + public boolean ConfirmProject(HttpServletRequest request, final String PROJECT_CODE) throws Exception { if( url == null || url.isEmpty() || user == null || user.isEmpty() || pw == null || pw.isEmpty() ) { @@ -605,6 +773,40 @@ public class WebConfirm "PROJECT_CODE:[" + PROJECT_CODE + "]\n" + "\n--------------------------------------------------------------\n" ); + + // 표준관입시험 심도 중복체크 + Map validationResult = validationCheckTempSpt(request, PROJECT_CODE); + + // 유효성 검증에 실패하면(중복 발견), 오류 메시지를 포함한 예외를 발생시켜 롤백 처리 + if (!(Boolean) validationResult.get("success")) { + String errorMessage = (String) validationResult.get("errorMessage"); + logger.warn("SPT validation failed for PROJECT_CODE [{}]: {}", PROJECT_CODE, errorMessage); + + // SQLException을 발생시켜 ConfirmProject의 catch 블록에서 롤백이 일어나도록 함 + throw new SQLException("등록에 실패하였습니다.\\n\\n기본현장시험 정보 중 표준관입시험의 심도(m) 값이 중복되었습니다. 심도(m)는 중복 될 수 없습니다. 중복 제거 후 재시도바랍니다:\\n\\n" + errorMessage); + } + + + + // 현장투수시험 심도 중복체크 + Map validationResultTempFieldperSub = validationCheckTempFieldperSub(request, PROJECT_CODE); + + // 유효성 검증에 실패하면(중복 발견), 오류 메시지를 포함한 예외를 발생시켜 롤백 처리 + if (!(Boolean) validationResultTempFieldperSub.get("success")) { + String errorMessage = (String) validationResultTempFieldperSub.get("errorMessage"); + logger.warn("SPT validation failed for PROJECT_CODE [{}]: {}", PROJECT_CODE, errorMessage); + + // SQLException을 발생시켜 ConfirmProject의 catch 블록에서 롤백이 일어나도록 함 + throw new SQLException("등록에 실패하였습니다.\\n\\n기본현장시험 정보 중 현장투수시험의 시간간격(sec) 값이 중복되었습니다. 시간간격(sec)은 중복 될 수 없습니다. 중복 제거 후 재시도바랍니다:\\n\\n" + errorMessage); + } + + System.out.println( + "\n--------------------------------------------------------------\n" + + request.getRequestURI() + " " + " SPT validation check is done." + + "\n--------------------------------------------------------------\n" + + "PROJECT_CODE:[" + PROJECT_CODE + "]\n" + + "\n--------------------------------------------------------------\n" + ); sql = " \n INSERT INTO TBL_SPT(HOLE_CODE, DEPTH_SPT, SPT_N, SPT_DEPTH ) "; sql += " \n SELECT HOLE_CODE, DEPTH_SPT, SPT_N, SPT_DEPTH FROM TEMP_SPT WHERE PROJECT_CODE = [PROJECT_CODE] "; @@ -1616,6 +1818,7 @@ public class WebConfirm } catch (SQLException sqle) { System.out.println("e.getMessage() : " + sqle.getMessage()); + throw sqle; } } try { @@ -1632,7 +1835,9 @@ public class WebConfirm } catch (SQLException sqe) { System.out.println("e.getMessage() : " + sqe.getMessage()); + throw sqe; } + throw e; } catch (Exception e) { @@ -1643,6 +1848,7 @@ public class WebConfirm } catch (SQLException sqle) { System.out.println("e.getMessage() : " + sqle.getMessage()); + throw sqle; } } try { @@ -1659,7 +1865,9 @@ public class WebConfirm } catch (SQLException sqe) { System.out.println("e.getMessage() : " + sqe.getMessage()); + throw sqe; } + throw e; } finally { try { diff --git a/src/main/java/geoinfo/regi/holeCoordinate/HoleCoordinateController.java b/src/main/java/geoinfo/regi/holeCoordinate/HoleCoordinateController.java index 0b31935f..f6e3c793 100644 --- a/src/main/java/geoinfo/regi/holeCoordinate/HoleCoordinateController.java +++ b/src/main/java/geoinfo/regi/holeCoordinate/HoleCoordinateController.java @@ -220,25 +220,12 @@ public class HoleCoordinateController { String COORD_SYS = sUtil.checkNull(String.valueOf(params.get("COORD_SYS_" + i))); String HOLE_OR_X = sUtil.checkNull(String.valueOf(params.get("HOLE_OR_X_" + i))); String HOLE_OR_Y = sUtil.checkNull(String.valueOf(params.get("HOLE_OR_Y_" + i))); - // String HOLE_LOCATION_X = sUtil.checkNull(String.valueOf(params.get("HOLE_LOCATION_X_" + i))); - // String HOLE_LOCATION_Y = sUtil.checkNull(String.valueOf(params.get("HOLE_LOCATION_Y_" + i))); - // 경위도 -> GRS80 중부원점 20-60 좌표로 변환 - // Map map = wUtil.setCoordinateChgXY(Double.parseDouble(HOLE_LOCATION_X), Double.parseDouble(HOLE_LOCATION_Y), "4326", "5186"); spParams.put("holeCode", HOLE_CODE); - spParams.put("isOrgInclude", 0); + spParams.put("isOrgInclude", 1); spParams.put("coordSys", Integer.parseInt(COORD_SYS)); spParams.put("orgX", Double.parseDouble(HOLE_OR_X)); - spParams.put("orgY", Double.parseDouble(HOLE_OR_Y)); - // params.put("HOLE_CODE", HOLE_CODE); - // params.put("HOLE_OR_X", HOLE_OR_X); - // params.put("HOLE_OR_Y", HOLE_OR_Y); - // params.put("HOLE_LOCATION_X", HOLE_LOCATION_X); - // params.put("HOLE_LOCATION_Y", HOLE_LOCATION_Y); - // params.put("tmX", map.get("X").toString()); - // params.put("tmY", map.get("Y").toString()); - // masterService.upCoord1(params); - // masterService.upCoord2(params); + spParams.put("orgY", Double.parseDouble(HOLE_OR_Y)); masterService.changeCoordHole(request, response, spParams); } model.setViewName("redirect:/holeCoord.do"); diff --git a/src/main/java/geoinfo/regi/status/RegiController.java b/src/main/java/geoinfo/regi/status/RegiController.java index 84b573e3..40a793ec 100644 --- a/src/main/java/geoinfo/regi/status/RegiController.java +++ b/src/main/java/geoinfo/regi/status/RegiController.java @@ -7,6 +7,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; +import java.sql.SQLException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -715,10 +716,7 @@ public class RegiController { WebConfirm confirm = new WebConfirm(); boolean confirmYN = false; - // 시추, 물리 TEMP -> TBL로 변경 confirmYN = confirm.ConfirmProject(request, PROJECT_CODE); - // ------------------------------------------------------- TBL이동 - // End System.out.println( "\n--------------------------------------------------------------\n" + @@ -810,6 +808,7 @@ public class RegiController { LOGGER.debug("error" + e); model.addAttribute("proce", e); affectRow = 0; + model.addAttribute("errorMessage", e.getMessage()); } model.addAttribute("projectCode", PROJECT_CODE); diff --git a/src/main/webapp/WEB-INF/views/web/manage/list_db.jsp b/src/main/webapp/WEB-INF/views/web/manage/list_db.jsp index 07956e9c..28c86256 100644 --- a/src/main/webapp/WEB-INF/views/web/manage/list_db.jsp +++ b/src/main/webapp/WEB-INF/views/web/manage/list_db.jsp @@ -1,21 +1,26 @@ <%@ page language="java" contentType = "text/html; charset=utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@ page isELIgnored="false" %> <% %> - + - - - - - - - + + + + + + + + + + + + + + diff --git a/src/main/webapp/com/img/map-service/icon/ico_map_right_control_steep_slope.png b/src/main/webapp/com/img/map-service/icon/ico_map_right_control_steep_slope.png index 5d561a50..8bc78b27 100644 Binary files a/src/main/webapp/com/img/map-service/icon/ico_map_right_control_steep_slope.png and b/src/main/webapp/com/img/map-service/icon/ico_map_right_control_steep_slope.png differ diff --git a/src/main/webapp/js/map/main/map.js b/src/main/webapp/js/map/main/map.js index 5a39eeae..08b4be83 100644 --- a/src/main/webapp/js/map/main/map.js +++ b/src/main/webapp/js/map/main/map.js @@ -317,6 +317,8 @@ var VWORLD_URL = "https://xdworld.vworld.kr/2d/Base/service/${z}/${x}/${y}.png // TBL_HEADER_HOLE 설정 // ------------------------------ var T_HOLE = "TBL_HEADER_HOLE"; +var T_WEB_STEEP_SLOPE = "WEB_STEEP_SLOPE"; // 급경사지 + var T_HOLE_M = "TBL_HEADER_HOLE_M"; var F_PROJECT_CODE = "PROJECT_CODE"; var F_HOLE_CODE = "HOLE_CODE"; @@ -643,6 +645,31 @@ function initApp(param){ removeBackBufferDelay : 0 } ); + + + // 급경사지 레이어 + STEEP_SLOPE_LAYER = new OpenLayers.Layer.WMS( + "WEB_STEEP_SLOPE", + O2MAP_URL, + { + isBaseLayer: false, + visibility: false, + layers : T_WEB_STEEP_SLOPE, + transparent : true, + format : "image/png", + crs : "EPSG:3857", + }, { + singleTile : false, + isBaseLayer : false, + visibility: getQueryString("masterCompanyCode") === null ? true : true, + transitionEffect: "resize", + buffer : 0, + removeBackBufferDelay : 0 + } + ); + + STEEP_SLOPE_LAYER.setVisibility(false); + /* if( getQueryString("masterCompanyCode") && true ) { HOLE_DRILLING = new OpenLayers.Layer.WMS( @@ -798,7 +825,10 @@ function initApp(param){ BASE_MAP.addLayer(HOLE_LAYER); }*/ - BASE_MAP.addLayer(HOLE_LAYER); + BASE_MAP.addLayer(HOLE_LAYER); + + STEEP_SLOPE_LAYER.mergeNewParams({version : '1.3.0'}); + BASE_MAP.addLayer(STEEP_SLOPE_LAYER); @@ -957,6 +987,9 @@ function initApp(param){ // 광산 레이어를 그 위(index 6)에 둡니다. BASE_MAP.setLayerIndex(MINE_LAYER, 6); + + // 급경사지 레이어를 그 위(index 7)에 둡니다. + BASE_MAP.setLayerIndex(STEEP_SLOPE_LAYER, 7); } // ▲▲▲ 레이어 순서(Z-index) 조정 코드 ▲▲▲ @@ -1108,7 +1141,7 @@ function initApp(param){ crs: "EPSG:3857", infoFormat: "application/json", //layers: [HOLE_LAYER,HOLE_LAYER_M], - layers: getQueryString("masterCompanyCode") === null ? [HOLE_LAYER] : [HOLE_LAYER], + layers: [HOLE_LAYER], queryVisible: true, maxFeatures: 1 }); @@ -5341,6 +5374,38 @@ function geologyWell() { //급경사지 버튼 눌렀을 때 호출됨. function geologySteepSlope() { - initControl(); // 다른 컨트롤 상태 초기화 - alert('급경사지 보기 기능이 곧 오픈됩니다.'); + initControl(); // 다른 컨트롤 상태 초기화 + + // STEEP_SLOPE_LAYER 가 정상적으로 생성되었는지 확인 + if (!STEEP_SLOPE_LAYER) { + console.error("급경사지 레이어가 초기화되지 않았습니다."); + return; + } + + // 현재 레이어의 표시 상태를 가져옵니다. + var isVisible = STEEP_SLOPE_LAYER.getVisibility(); + + if (isVisible ) { + // 레이어가 현재 보이고 있다면, 숨깁니다. + STEEP_SLOPE_LAYER.setVisibility(false); + CTL_INFO.setText("급경사지 Off"); + CTL_INFO.deactivate(); // 정보창도 비활성화 + + } else { + + // 레이어를 보이게 설정하고 강제로 다시 그립니다. + STEEP_SLOPE_LAYER.setVisibility(true); + STEEP_SLOPE_LAYER.redraw(true); + + // CTL_INFO의 infoDiv가 내부 요소를 absolute 포지셔닝할 수 있도록 'relative'로 설정 + $(CTL_INFO.infoDiv).css("position", "relative"); + + // CTL_INFO 텍스트 설정 시 버튼 HTML을 함께 삽입 + CTL_INFO.setText("급경사지 On"); + CTL_INFO.activate(); + $("#CTL_INFO").css("bottom", "65px"); + $("#CTL_INFO").css("left", "20px"); + alert('급경사지 정보는 빨간색 선으로 보여집니다.'); + } + } \ No newline at end of file