diff --git a/src/main/webapp/WEB-INF/views/map/index.jsp b/src/main/webapp/WEB-INF/views/map/index.jsp
index 43efaf3d..5bae744d 100644
--- a/src/main/webapp/WEB-INF/views/map/index.jsp
+++ b/src/main/webapp/WEB-INF/views/map/index.jsp
@@ -264,19 +264,19 @@ function LoadingShow() {
레이어
- -
+
-
지질
- -
+
-
광산
- -
+
-
관정
- -
+
-
급경사지
diff --git a/src/main/webapp/com/css/map-service.css b/src/main/webapp/com/css/map-service.css
index bf933ac5..a3c4bfae 100644
--- a/src/main/webapp/com/css/map-service.css
+++ b/src/main/webapp/com/css/map-service.css
@@ -875,6 +875,17 @@ header .global-link-wrapper {
.map-right-btn-group > li .map-right-btn.map-btn-icon-steep-slope::before {
background: url(../img/map-service/icon/ico_map_right_control_steep_slope.png) no-repeat 50% 50%;
}
+.map-right-btn-group > li.active {
+ background: #0053b7;
+}
+.map-right-btn-group > li.active > a.map-right-btn{
+ color: #ffffff;
+}
+
+.map-right-btn-group > li.active > a.map-right-btn:before {
+ filter: invert(100%);
+ -webkit-filter: invert(100%); /* 구형 브라우저 호환 */
+}
/* 지도구분 탭 시작 */
diff --git a/src/main/webapp/js/map/main/map.js b/src/main/webapp/js/map/main/map.js
index c723c8a5..1cb85607 100644
--- a/src/main/webapp/js/map/main/map.js
+++ b/src/main/webapp/js/map/main/map.js
@@ -21,6 +21,40 @@ function loadScript(url, callback) {
}
+
+function hasClass(element, cls) {
+ if (!element) return false;
+ // 클래스명 앞뒤에 공백을 넣어 정확한 단어 일치 확인
+ return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
+}
+
+function removeClassOverlayLayer(targetEleId) {
+ var targetBtn = document.getElementById(targetEleId);
+ var toggleClass = 'active';
+
+ if (!targetBtn) {
+ console.error(targetEleId + " 버튼이 존재하지 않습니다.");
+ return;
+ }
+
+ if (hasClass(targetBtn, toggleClass)) {
+ var reg = new RegExp('(\\s|^)' + toggleClass + '(\\s|$)');
+ targetBtn.className = targetBtn.className.replace(reg, ' ');
+ }
+}
+
+function addClassOverlayLayer(targetEleId) {
+ var targetBtn = document.getElementById(targetEleId);
+ var toggleClass = 'active';
+
+ if (!targetBtn) {
+ console.error(targetEleId + " 버튼이 존재하지 않습니다.");
+ return;
+ }
+ targetBtn.className += " " + toggleClass;
+}
+
+
//발주기관 용 js는 동적으로 로딩한다.
if(document.getElementById("cls").value == '2'){
loadScript('/js/map/main/map_boundary.js?v=20250617_094801', function() {
@@ -422,17 +456,18 @@ var T_LAND_AS = "UGG_LTHF_AS";
// -------------------------------
// Static variable
// -------------------------------
-var BASE_MAP; // 지도
+var BASE_MAP; // 지도
-var HOLE_LAYER; // 시추공 레이어
-var HOLE_LAYER_M; // 시추공 레이어2
-var GEOLOGY_LAYER; // 지질도/광물 레이어
-var MINERAL_LAYER; // 광물 레이어
-var MINE_LAYER; // 광산 레이어
-var CTL_SELECT_MINE; // 광산 선택
-var WELL_LAYER; // 관정 레이어
-var STEEP_SLOPE_LAYER; // 급경사지 레이어
-var CTL_SELECT_SLOPE; // 급경사지 선택
+var HOLE_LAYER; // 시추공 레이어
+var HOLE_LAYER_M; // 시추공 레이어2
+var GEOLOGY_LAYER; // 지질도/광물 레이어
+var MINERAL_LAYER; // 광물 레이어
+var MINE_LAYER; // 광산 레이어
+var CTL_SELECT_MINE; // 광산 선택
+var CTL_SELECT_MINE_HOVER; // 광산 선택 (호버/커서용)
+var WELL_LAYER; // 관정 레이어
+var STEEP_SLOPE_LAYER; // 급경사지 레이어
+var CTL_SELECT_SLOPE; // 급경사지 선택
var HOLE_SELECT; // 시추공 선택
var HOLE_SELECT2; // 3d지반
@@ -1072,23 +1107,22 @@ function initApp(param){
CTL_SELECT_MINE = new OpenLayers.Control.SelectFeature(MINE_LAYER, {
clickout: true, toggle: true,
multiple: false, hover: false,
- onSelect: function(feature) {
+ onSelect: function(feature) {
var mgtNo = feature.attributes.MGTNO;
var objectId = feature.attributes.OBJECTID;
- // 관리번호가 없는 경우 처리
if (!mgtNo || mgtNo === "정보없음") {
alert("관리번호 정보가 없습니다.");
this.unselect(feature);
return;
}
-
- // 백엔드 프록시('/map/getMineInfo.do')를 통해 API 호출
+
+ // API 호출
$.ajax({
url: "/map/getMineInfo.do",
type: "GET",
data: { mgtNo: mgtNo },
- dataType: "json", // JSON 문자열을 그대로 받기 위해 text 사용
+ dataType: "json",
success: function(data) {
//mgtNo가 같아도 다른 광산이 많이 존재한다... 필요시 하드 코딩을 하기 위해, 아래 전국 mineList를 JSON으로 정리해서 특정 광산과 연결하도록 구현하였다.
@@ -1228,6 +1262,28 @@ function initApp(param){
}
});
BASE_MAP.addControl(CTL_SELECT_MINE);
+
+
+ // 광산 호버(마우스 오버) 컨트롤 생성
+ // highlightOnly: true로 설정하여 선택(클릭) 로직은 실행하지 않고,
+ // 마우스가 올라갔을 때 스타일(cursor: pointer)만 적용되도록 합니다.
+ CTL_SELECT_MINE_HOVER = new OpenLayers.Control.SelectFeature(MINE_LAYER, {
+ hover: true,
+ highlightOnly: true,
+ renderIntent: "temporary",
+ // 이벤트 리스너를 추가하여 커서 모양을 수동으로 제어
+ eventListeners: {
+ // 마우스가 광산 아이콘 위에 올라갔을 때
+ featurehighlighted: function(e) {
+ BASE_MAP.div.style.cursor = "pointer";
+ },
+ // 마우스가 광산 아이콘에서 벗어났을 때
+ featureunhighlighted: function(e) {
+ BASE_MAP.div.style.cursor = "";
+ }
+ }
+ });
+ BASE_MAP.addControl(CTL_SELECT_MINE_HOVER);
// ▲▲▲ 광산정보 (WFS Custom Parsing & Selection) ▲▲▲
@@ -4374,7 +4430,7 @@ function getStyleDRAW(){
// -------------------------------------
// 컨트롤 초기화
// -------------------------------------
-function initControl(){
+function initControl(targetEleId){
onTest = false;
onCircleLine = false;
@@ -4390,8 +4446,9 @@ function initControl(){
HOLE_SELECT.removeAllFeatures();
HOLE_SELECT2.removeAllFeatures();
CTL_SELECT.deactivate();
- if(CTL_SELECT_SLOPE) CTL_SELECT_SLOPE.deactivate(); // 급경사지 선택 비활성화
- if(CTL_SELECT_MINE) CTL_SELECT_MINE.deactivate(); // 광산 선택 비활성화
+ if(CTL_SELECT_SLOPE) CTL_SELECT_SLOPE.deactivate(); // 급경사지 선택 비활성화
+ if(CTL_SELECT_MINE) CTL_SELECT_MINE.deactivate(); // 광산 선택 비활성화
+ if(CTL_SELECT_MINE_HOVER) CTL_SELECT_MINE_HOVER.deactivate(); // 광산 호버 컨트롤 비활성화
CTL_SELECT_PROJECT.deactivate();
CTL_SELECT_JIBAN.deactivate();
CTL_TOOLTIP.activate();
@@ -4425,23 +4482,32 @@ function initControl(){
}
initCoordinateRadioControl();
+
+ initOverlayLayers(targetEleId);
+ removeGeologyLegend();
- if( GEOLOGY_LAYER && GEOLOGY_LAYER.active ) {
- GEOLOGY_LAYER.deactivate();
+}
+
+/**
+ * 지질도, 광산, 관정, 급경사지 레이어를 끈다.
+ * @param targetEleId: 이 값은 null일 수도 있음. 지질을 눌렀는지 광산을 눌렀는지 관정을 눌렀는지 급경사지를 눌렀는지 구분하여 해당 레이어는 안 끄도록 설정한다.
+ * @returns
+ */
+function initOverlayLayers(targetEleId) {
+ offOverlayLayer(targetEleId, 'map-btn-icon-geology-button', GEOLOGY_LAYER);
+ offOverlayLayer(targetEleId, 'map-btn-icon-mine-button', MINE_LAYER);
+ offOverlayLayer(targetEleId, 'map-btn-icon-well-button', WELL_LAYER);
+ offOverlayLayer(targetEleId, 'map-btn-icon-steep-slope-button', STEEP_SLOPE_LAYER);
+}
+
+function offOverlayLayer(targetEleId, myEleId, LAYER) {
+ if( LAYER ) {
+ if( targetEleId === myEleId) {
+ } else {
+ LAYER.setVisibility(false);
+ removeClassOverlayLayer(myEleId);
+ }
}
-
- if( MINE_LAYER && MINE_LAYER.active ) {
- MINE_LAYER.deactivate();
- }
-
- if( WELL_LAYER && WELL_LAYER.active ) {
- WELL_LAYER.deactivate();
- }
-
- if( STEEP_SLOPE_LAYER && STEEP_SLOPE_LAYER.active ) {
- STEEP_SLOPE_LAYER.deactivate();
- }
-
}
function initCoordinateControl(){
@@ -5816,27 +5882,69 @@ function showGeologyLegend() {
-function geologyMode() {
- initControl(); // 다른 컨트롤 상태 초기화
+function toggleOverlayLayer(liEleId, layerName, LAYER, message) {
- // GEOLOGY_LAYER가 정상적으로 생성되었는지 확인
- if (!GEOLOGY_LAYER) {
- console.error("지질도 레이어가 초기화되지 않았습니다.");
+ initControl(liEleId); // 다른 컨트롤 상태 초기화
+
+ if (!LAYER) {
+ console.error( layerName + " 레이어가 초기화되지 않았습니다.");
return;
+ }
+
+ var isVisible = LAYER.getVisibility();
+
+ var targetBtn = document.getElementById(liEleId);
+ var toggleClass = 'active';
+
+ if (hasClass(targetBtn, toggleClass)) {
+ removeClassOverlayLayer(liEleId);
+
+ // 레이어 숨김 -> 컨트롤 비활성화
+ LAYER.setVisibility(false);
+ // 레이어가 안 보이므로 선택 기능도 끕니다.
+ if (CTL_SELECT_SLOPE) CTL_SELECT_SLOPE.deactivate();
+
+ CTL_INFO.setText(layerName + " Off");
+ CTL_INFO.deactivate();
+ } else {
+ addClassOverlayLayer(liEleId);
+
+ // [ON 처리] 레이어 표시 -> 컨트롤 활성화 (선택 모드 여부 상관없음)
+ LAYER.setVisibility(true);
+ LAYER.redraw(true);
+
+ // 레이어가 보이면 무조건 선택 기능을 켭니다.
+ if (CTL_SELECT_SLOPE) {
+ CTL_SELECT_SLOPE.activate();
+ }
+
+ // 정보창 표시
+ $(CTL_INFO.infoDiv).css("position", "relative");
+ CTL_INFO.setText(layerName + " On");
+ CTL_INFO.activate();
+ $("#CTL_INFO").css("bottom", "65px");
+ $("#CTL_INFO").css("left", "20px");
+
+ showToast(message);
}
+ if (isVisible) {
+ } else {
+ }
+}
+
+function geologyMode() {
+ var liEleId = 'map-btn-icon-geology-button';
+ var layerName = '지질';
+ var message = '지질도 레이어 로딩 중...';
+ toggleOverlayLayer(liEleId, layerName, GEOLOGY_LAYER, message);
+
+
+
// 현재 레이어의 표시 상태를 가져옵니다.
var isVisible = GEOLOGY_LAYER.getVisibility();
if (isVisible && geologyLayersKey === "지질도_25만_지질도" ) {
- // 레이어가 현재 보이고 있다면, 숨깁니다.
- GEOLOGY_LAYER.setVisibility(false);
- CTL_INFO.setText("지질 Off");
- CTL_INFO.deactivate(); // 정보창도 비활성화
-
- removeGeologyLegend(); // 지질도를 끌 때 범례도 닫습니다.
-
- } else {
// 레이어가 현재 숨겨져 있다면,
// 1. 표시할 기본 지질도 키를 설정합니다.
geologyLayersKey = "지질도_25만_지질도";
@@ -5848,34 +5956,12 @@ function geologyMode() {
// 3. 레이어 객체의 url 속성을 직접 변경합니다.
GEOLOGY_LAYER.url = newUrl;
-
- // 4. 레이어를 보이게 설정하고 강제로 다시 그립니다.
- GEOLOGY_LAYER.setVisibility(true);
- GEOLOGY_LAYER.redraw(true);
-
- // 5. 정보창 텍스트 및 버튼을 업데이트합니다.
-
- // '범례 보기' 버튼 HTML 정의 (이전 단계에서 수정한 내용)
- var legendButtonHtml = '' +
- '범례 보기
';
-
- // CTL_INFO의 infoDiv가 내부 요소를 absolute 포지셔닝할 수 있도록 'relative'로 설정
- $(CTL_INFO.infoDiv).css("position", "relative");
-
- // CTL_INFO 텍스트 설정 시 버튼 HTML을 함께 삽입
- //CTL_INFO.setText("지질 On" + legendButtonHtml);
- CTL_INFO.setText("지질 On");
- CTL_INFO.activate();
showGeologyLegend();
- $("#CTL_INFO").css("bottom", "65px");
- $("#CTL_INFO").css("left", "20px");
-
} else {
console.error("기본 지질도 레이어를 찾을 수 없습니다:", geologyLayersKey);
}
+ } else {
+ removeGeologyLegend(); // 지질도를 끌 때 범례도 닫습니다.
}
}
@@ -5986,149 +6072,66 @@ function geologyMineral() {
}
function geologyMine() {
- initControl(); // 다른 컨트롤 초기화
-
- if (!MINE_LAYER) {
- console.error("광산 레이어가 초기화되지 않았습니다.");
- alert("오류: 광산 레이어가 없습니다.");
- return;
- }
+ var liEleId = 'map-btn-icon-mine-button';
+ var layerName = '광산';
+ var message = '광산은 공개된 데이터가 많지 않습니다. 빨간색 사각형으로 표시됩니다.';
+ toggleOverlayLayer(liEleId, layerName, MINE_LAYER, message);
var isVisible = MINE_LAYER.getVisibility();
-
if (isVisible) {
- // [OFF] 기능 끄기
- MINE_LAYER.setVisibility(false);
- if(CTL_SELECT_MINE) CTL_SELECT_MINE.deactivate();
-
- CTL_INFO.setText("지질 Off");
- CTL_INFO.deactivate();
- removeGeologyLegend();
- console.log("[광산] 레이어 OFF");
-
- } else {
- // [ON] 기능 켜기
- MINE_LAYER.setVisibility(true);
-
- // 레이어 Z-Index를 최상위로 설정
- // 다른 레이어(WMS, 툴팁 등)보다 무조건 위에 오도록 값을 높게 설정합니다.
+ // 1. Z-Index 최상위 설정
var maxZ = 0;
for(var i=0; i maxZ) {
maxZ = BASE_MAP.layers[i].getZIndex();
}
}
- MINE_LAYER.setZIndex(maxZ + 500); // 가장 높은 값보다 500 더 높게
+ MINE_LAYER.setZIndex(maxZ + 1000);
MINE_LAYER.redraw(true);
- // 선택 컨트롤 재활성화 및 로그 출력
- if(CTL_SELECT_MINE) {
- CTL_SELECT_MINE.deactivate();
- var activated = CTL_SELECT_MINE.activate();
+ // 2. 컨트롤 초기화 (일단 끔)
+ if(CTL_SELECT_MINE) CTL_SELECT_MINE.deactivate();
+ if(CTL_SELECT_MINE_HOVER) CTL_SELECT_MINE_HOVER.deactivate();
+
+ // 3. 호버 컨트롤 먼저 활성화 (이벤트 통과 설정)
+ if(CTL_SELECT_MINE_HOVER) {
+ CTL_SELECT_MINE_HOVER.activate();
- // 현재 로드된 피처 개수 확인
- var featureCount = MINE_LAYER.features.length;
- console.log("[광산] 컨트롤 활성화 성공여부: " + activated);
- console.log("[광산] 현재 지도에 표시된 광산 개수: " + featureCount);
-
- if(featureCount > 0) {
- console.log("[광산] 첫번째 광산 속성 예시:", MINE_LAYER.features[0].attributes);
+ // 클릭 이벤트를 가로채지 않고 통과시키도록 설정
+ if(CTL_SELECT_MINE_HOVER.handlers && CTL_SELECT_MINE_HOVER.handlers.feature) {
+ CTL_SELECT_MINE_HOVER.handlers.feature.stopDown = false;
+ CTL_SELECT_MINE_HOVER.handlers.feature.stopUp = false;
}
-
- } else {
- console.error("[광산] CTL_SELECT_MINE 컨트롤이 없습니다! initApp에서 생성되었는지 확인하세요.");
- alert("오류: 광산 선택 컨트롤이 생성되지 않았습니다.");
}
-
- $(CTL_INFO.infoDiv).css("position", "relative");
- CTL_INFO.setText("광산 On");
- CTL_INFO.activate();
- $("#CTL_INFO").css("bottom", "65px");
- $("#CTL_INFO").css("left", "20px");
+ // 4. [순서 변경] 클릭 컨트롤 나중에 활성화 (이벤트 우선순위 확보)
+ if(CTL_SELECT_MINE) {
+ CTL_SELECT_MINE.activate();
+ }
- alert('광산은 공개된 데이터가 많지 않습니다. 빨간색 사각형으로 표시됩니다.');
- }
+ } else {
+ // 기능 비활성화 시 정리
+ MINE_LAYER.setZIndex(6);
+ if(CTL_SELECT_MINE) CTL_SELECT_MINE.deactivate();
+ if(CTL_SELECT_MINE_HOVER) CTL_SELECT_MINE_HOVER.deactivate();
+ }
}
// 관정 보기 버튼 눌렀을 때 호출됨.
function geologyWell() {
- initControl(); // 다른 컨트롤 상태 초기화
-
- // WELL_LAYER 가 정상적으로 생성되었는지 확인
- if (!WELL_LAYER) {
- console.error("관정 레이어가 초기화되지 않았습니다.");
- return;
- }
-
- // 현재 레이어의 표시 상태를 가져옵니다.
- var isVisible = WELL_LAYER.getVisibility();
-
- if (isVisible ) {
- // 레이어가 현재 보이고 있다면, 숨깁니다.
- WELL_LAYER.setVisibility(false);
- CTL_INFO.setText("관정 Off");
- CTL_INFO.deactivate(); // 정보창도 비활성화
- //removeGeologyLegend(); // 끌 때 범례도 닫습니다.
-
- } else {
-
- // 레이어를 보이게 설정하고 강제로 다시 그립니다.
- WELL_LAYER.setVisibility(true);
- WELL_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('관정 정보는 지도를 최대로 확대시에만 보여집니다.');
- }
+ var liEleId = 'map-btn-icon-well-button';
+ var layerName = '관정';
+ var message = '관정 정보는 지도를 최대로 확대시에만 보여집니다.';
+ toggleOverlayLayer(liEleId, layerName, WELL_LAYER, message);
}
//급경사지 버튼 눌렀을 때 호출됨.
function geologySteepSlope() {
-
- if (!STEEP_SLOPE_LAYER) {
- console.error("급경사지 레이어가 초기화되지 않았습니다.");
- return;
- }
-
- var isVisible = STEEP_SLOPE_LAYER.getVisibility();
-
- if (isVisible) {
- // [OFF 처리] 레이어 숨김 -> 컨트롤 비활성화
- STEEP_SLOPE_LAYER.setVisibility(false);
-
- // 레이어가 안 보이므로 선택 기능도 끕니다.
- if (CTL_SELECT_SLOPE) CTL_SELECT_SLOPE.deactivate();
-
- CTL_INFO.setText("급경사지 Off");
- CTL_INFO.deactivate();
-
- } else {
- // [ON 처리] 레이어 표시 -> 컨트롤 활성화 (선택 모드 여부 상관없음)
- STEEP_SLOPE_LAYER.setVisibility(true);
- STEEP_SLOPE_LAYER.redraw(true);
-
- // 레이어가 보이면 무조건 선택 기능을 켭니다.
- if (CTL_SELECT_SLOPE) {
- CTL_SELECT_SLOPE.activate();
- }
-
- // 정보창 표시
- $(CTL_INFO.infoDiv).css("position", "relative");
- CTL_INFO.setText("급경사지 On");
- CTL_INFO.activate();
- $("#CTL_INFO").css("bottom", "65px");
- $("#CTL_INFO").css("left", "20px");
-
- alert('급경사지 정보는 빨간색 선으로 보여집니다.');
- }
+ var liEleId = 'map-btn-icon-steep-slope-button';
+ var layerName = '급경사지';
+ var message = '급경사지 정보는 빨간색 선으로 보여집니다.';
+ toggleOverlayLayer(liEleId, layerName, STEEP_SLOPE_LAYER, message);
}
@@ -6165,7 +6168,8 @@ function geologyResistivitySurvey() {
CTL_INFO.activate();
$("#CTL_INFO").css("bottom", "65px");
$("#CTL_INFO").css("left", "20px");
- alert('급경사지 정보는 빨간색 선으로 보여집니다.');
+
+ showToast('급경사지 정보는 빨간색 선으로 보여집니다.');
}
}
\ No newline at end of file