오늘도 돌아온 작업 내용 정리 시간!
오늘은 리스트 클릭 시 해당 지역에 마커가 찍히면서 충전소 상세정보 팝업이 뜨게 하기!
✅ 리스트 클릭 시 해당 지역 마커 + 상세정보 팝업
마지막까지의 작업 내용 ↓
여기에 이어서 리스트 클릭 시 카카오 지도에 마커를 전달하면서 해당 위치로 이동하게 한 후 팝업창이 나오게 구현했다.
리스트를 만들때 사용했던 lat, lng (위도,경도)를 이용해서 kakaomap에 전달했고 전달받은 값에 마커가 찍히게 했다.
위도와 경도 + 각종 팝업창에 띄울 필요한 값들을 생각해서 클릭 시 같이 전달하게 했다.
listItem.addEventListener("click", function () {
const stationData = {
name: displayName, // 충전소명 (중복 구분 포함)
operator: busiNm, // 운영기관명
contact: busiCall, // 운영기관 연락처
address: addr, // 주소
addressDetail: addrDetail, // 상세주소
useTime: useTime, // 이용 가능 시간
output: output, // 충전 용량
type: type, // 충전기 타입 코드
status: stat, // 충전기 상태 코드
statusUpdateDate: statUpdDt, // 상태갱신일시
lastStart: lastTsdt, // 마지막 충전 시작 일시
lastEnd: lastTedt, // 마지막 충전 종료 일시
chargingStart: nowTsdt, // 현재 충전 시작 일시
note: note, // 충전소 안내
limitDetail: limitDetail, // 이용 제한 사항
lat: lat, // 위도
lng: lng // 경도
};
showStationInfoPopup(stationData);
const selectedLocation = new kakao.maps.LatLng(lat, lng);
map.setCenter(selectedLocation);
const marker = new kakao.maps.Marker({
position: selectedLocation,
map: map
});
});
다음으로는 상세정보 팝업을 우측에 띄우려고 했다.
일단 먼저 최종 결과물!
우측에 큰 div에서 각각 항목별로 flex-direction: column;값을 주고 각 항목마다 div를 두고 조절하면서 사용했다.
사용하고 있는 공공데이터API에서는 충전기 타입이나, 충전기 상태 등등을 숫자로만 주고 있었기 때문에
기존에 작업할때 사용했던 값들을 그대로 받아서 쓰게 했다.
예시_
const chargerTypeMap = {
"01": "DC차데모",
"02": "AC완속",
"03": "DC차데모+AC3상",
"04": "DC콤보",
"05": "DC차데모+DC콤보",
"06": "DC차데모+AC3상+DC콤보",
"07": "AC3상",
"08": "DC콤보(완속)",
"89": "H2"
};
const chargerStatusMap = {
"1": { text: "사용 불가", class: "status-unavailable" },
"2": { text: "사용 가능", class: "status-available" },
"3": { text: "사용 중", class: "status-in-use" },
"4": { text: "운영 중지", class: "status-out-of-service" },
"5": { text: "점검 중", class: "status-under-maintenance" },
"9": { text: "상태 미확인", class: "status-unknown" }
};
이런식으로 01에 해당하는 충전기 타입, 1에 해당하는 충전기 상태를 정의했었는데
그걸 그대로 사용하게 전역으로 정의하고
팝업창이 열릴때 값을 받을 수 있게 했다.
// 충전소 정보를 팝업에 표시하는 함수
function showStationInfoPopup(stationData) {
// 타입과 상태 정보를 전역 매핑 객체를 사용해 변환
const typeText = chargerTypeMap[stationData.type] || "알 수 없는 타입";
const statusInfo = chargerStatusMap[stationData.status] || { text: "알 수 없는 상태", class: "status-unknown" };
document.getElementById("popupType").textContent = typeText;
document.getElementById("popupStatus").textContent = statusInfo.text; // 상태 텍스트 설정
document.getElementById("popupStatus").className = `status-button ${statusInfo.class}`; // 상태 클래스 설정
const formattedDate = formatDate(stationData.statusUpdateDate);
// 로드뷰 설정을 위한 변수들
const roadviewContainer = document.getElementById('roadview'); // 로드뷰를 표시할 div
const roadview = new kakao.maps.Roadview(roadviewContainer); // 로드뷰 객체
const roadviewClient = new kakao.maps.RoadviewClient(); // 좌표로부터 로드뷰 파노ID를 가져올 로드뷰 helper 객체
// 팝업창에 데이터 설정
document.getElementById("popupStationName").textContent = stationData.name; //충전소 이름
// 모든 data-value="popupOperator" 요소에 운영기관 이름 설정
document.querySelectorAll("[data-value='popupOperator']").forEach(el => {
el.textContent = stationData.operator || "정보 없음";
});
document.getElementById("popupContact").textContent = stationData.contact || "정보 없음"; //운영기관 연락처
document.getElementById("popupAddress").textContent = stationData.address; //충전소 주소
//document.getElementById("popupDetailedLocation").textContent = stationData.addressDetail || "상세 주소 없음"; //충전소 상세 주소
document.getElementById("popupUseTime").textContent = stationData.useTime || "정보 없음"; //이용 가능 시간
document.getElementById("popupType").textContent = chargerTypeMap[stationData.type] || "알 수 없는 타입"; //충전기 타입
document.getElementById("popupStatus").textContent = chargerStatusMap[stationData.status]?.text || "알 수 없는 상태"; //충전기 상태
document.getElementById("popupOutput").textContent = `${stationData.output}kW` || "정보 없음"; // 충전 용량
//document.getElementById("popupStatusUpdateDate").textContent = stationData.statusUpdateDate || "정보 없음"; //상태 갱신 일시
//document.getElementById("popupLastStart").textContent = stationData.lastStart || "정보 없음"; // 마지막 충전 시작 일시
//document.getElementById("popupLastEnd").textContent = stationData.lastEnd || "정보 없음"; // 마지막 충전 종료 일시
//document.getElementById("popupChargingStart").textContent = stationData.chargingStart || "정보 없음"; // 현재 충전 시작 일시
document.getElementById("popupNote").textContent = stationData.note || "안내 정보 없음"; //충전소 안내
document.getElementById("popupLimitDetail").textContent = stationData.limitDetail || "제한 없음"; //이용자 제한사항
일단 어떤 값을 쓸지 몰라서 최대한 많은 값들을 가져오게 하고 안쓰는 값들은 주석처리로 일단 살려두기..
그러고 id값으로 전달하게 한 값들을 jsp요소 내에서 사용했다.
충전소 이름을 예로 들면
api에서 호출할때는 statNm이라는 값으로 받아서 statNm으로 저장하고
for (let i = 0; i < items.length; i++) {
const statNm = items[i].getElementsByTagName("statNm")[0].textContent; // 충전소명
사용하는 공공데이터API에서는 여러개의 충전기가 있으면 그냥 동일한 이름으로 제공했기 때문에
여러개의 충전기 이름이 중복되면 뒤에 숫자를 붙여서 충전기의 개수를 표현하고 싶어서 다시 재가공했다.
// 중복된 충전소명에 번호 붙이기
if (stationNameCount[statNm]) {
stationNameCount[statNm] += 1; // 중복 카운트 증가
} else {
stationNameCount[statNm] = 1; // 처음 등장하는 충전소명
}
const displayName = stationNameCount[statNm] > 1 ? `${statNm} (${stationNameCount[statNm]})` : statNm;
이렇게 statNm으로 받아서 최종적으로 저장된 displayName으로 저장했다.
그러고 충전소명은 click event가 발생하면
listItem.addEventListener("click", function () {
const stationData = {
name: displayName, // 충전소명 (중복 구분 포함)
...
};
showStationInfoPopup(stationData);
이렇게 name값으로 전달했고 이걸 다시 받아서 stationData로 넘겼다. 그럼 최종적으로 stationData.name!
이제 팝업창이 열리면 popupStationName의 id속성값에 stationData.name을 전달!
// 충전소 정보를 팝업에 표시하는 함수
function showStationInfoPopup(stationData) {
document.getElementById("popupStationName").textContent = stationData.name; //충전소 이름
...
<!-- 충전소 정보 팝업 -->
<div id="stationInfoPopup" class="station-info-popup">
<button id="closePopupButton">X</button>
<div class="real-popup">
<div class="popupStationName">
<span id="popupStationName"></span>
</div>
...
이렇게 JSP 내에서 span값에 popupStationName이라는 id값을 줘서 저기서 값을 받아서 표현하게 했다.
이런식으로 나머지 값들도 하나하나 가져오기!
같은 방식으로 필요한 값들 다 받아서
busiNm = 운영기관명 ✅
busiCall = 운영기관 연락처 ✅
addr = 주소 ✅
useTime = 이용가능시간 ✅
chgerType = 충전기 타입 ✅
stat = 충전기 상태 ✅
statUpdDt = 상태갱신일시 ✅
lastTsdt = 마지막 충전시작일시 ✅
lastTedt = 마지막 충전종료일시 ✅
nowTsdt = 충전중 시작일시 ✅
note = 충전소 안내 ✅
limitDetail = 이용자제한 ✅
그대로 팝업창에 구역 나눠서 출력했다!
충전기 상태에 상태 갱신시간을 새로 추가해서 언제 갱신이 됐는지 알 수 있게 했다.
카카오 지도 API 로드뷰 사용하기
다음으로 한건 위치사진에 카카오 지도 api에서 제공하고 있는 로드뷰 기능을 썼다.
(참고 사이트: https://apis.map.kakao.com/web/sample/basicRoadview/ )
//카카오 공식 문서
var roadviewContainer = document.getElementById('roadview'); //로드뷰를 표시할 div
var roadview = new kakao.maps.Roadview(roadviewContainer); //로드뷰 객체
var roadviewClient = new kakao.maps.RoadviewClient(); //좌표로부터 로드뷰 파노ID를 가져올 로드뷰 helper객체
var position = new kakao.maps.LatLng(33.450701, 126.570667);
// 특정 위치의 좌표와 가까운 로드뷰의 panoId를 추출하여 로드뷰를 띄운다.
roadviewClient.getNearestPanoId(position, 50, function(panoId) {
roadview.setPanoId(panoId, position); //panoId와 중심좌표를 통해 로드뷰 실행
});
어차피 위도,경도값은 이미 가지고 있으니까
이걸 그냥 카카오 로드뷰에 전달해서 해당 위치에 대한 로드뷰를 받아서 화면에 출력하기만 하면 됐다.
// 로드뷰 설정: 주어진 위도와 경도를 사용하여 로드뷰 표시
const position = new kakao.maps.LatLng(stationData.lat, stationData.lng); // 충전소의 위도와 경도
roadviewClient.getNearestPanoId(position, 50, function(panoId) {
if (panoId) {
roadview.setPanoId(panoId, position); // panoId와 중심좌표를 통해 로드뷰 실행
} else {
roadviewContainer.innerHTML = '<p>로드뷰를 사용할 수 없는 위치입니다.</p>'; // 로드뷰가 없는 경우 메시지 표시
}
});
이렇게 팝업창에서 전달받고 있는 stationData.lat, stationData.lng값을 그대로 로드뷰에 전달해서 완성했다.
최종적으로 테스트 한번 더 해보기
잘 전달받아서 출력하고 있다!
이제 앞으로 해야할것들
팝업창 나온 전기차 충전소 값을 충전소 길 찾기로 전달해서 도착지점으로 설정하기
충전소 길 찾기 스타일링
이러면 진짜 끝!
'Develop > JPA' 카테고리의 다른 글
전기차 충전소 API (6) (0) | 2024.11.14 |
---|---|
전기차 충전소 길찾기 (5) (0) | 2024.11.13 |
전기차 충전소 API 데이터 가공하기 (3) (2) | 2024.11.11 |
전기차 충전소 API 호출하기 (2) (0) | 2024.11.08 |
전기차 충전소 API 호출하기 (1) (0) | 2024.11.07 |