본문 바로가기
Develop/JPA

전기차 충전소 API 호출하기 (1)

by ys2ys2 2024. 11. 7.

충전소 길 찾기 부분은 어느정도 정리가 돼서 충전소 검색 기능을 추가하려고 한다!

 

일단 사용자에게 시/도와 시/군을 입력받아서 해당 시/도/군에 있는 전기차 충전소를 보여주려고 한다.

 

사용한 공공데이터API = https://www.data.go.kr/tcs/dss/selectApiDataDetailView.do?publicDataPk=15076352

공공데이터포털, 한국환경공단_전기자동차 충전소 정보

 

여기서 제공하는 값들이 구현하려고 하는 페이지의 기능들에 잘 맞았다.

충전소명, 충전소ID, 충전소 타입, 소재지 도로명 주소, 위도와 경도, 이용가능시간, 기관ID, 운영기관명, 관리업체 전화번호, 충전기 상태, 상태일시갱신(충전기 상태 변경 일시), 충전기 용량, 지역코드, 주차료 무료 여부, 충전소 안내(이용제한,주차요금)등 다양한 값들이랑 충전기 상태까지 나와서 실시간으로 충전기가 사용되고 있는지 여부도 알 수 있는 것 같았다.

 


 

 

API 활용가이드 확인하기!

 

 

API 사용하려면 활용가이드 정독!

 

 

 

이런식으로 API값을 요청할 수 있었고 응답 예시에서 주는 값들도 확인했다!

 

일단 먼저 사용자에게 시/군/구 값을 받아야 해서 지역구분 코드를 먼저 확인했다.

 

 


 

 

지역구분 코드, 지역구분 상세코드 확인하기

 

 

사용하려고 하는 공공데이터 API에서는 먼저 지역구분 코드 → 지역구분상세 코드 이렇게 프로세스가 진행되고 있었다.

지역구분 코드
지역구분 상세코드

 

 

그래서 먼저 지역구분 코드를 입력받을 드롭다운 리스트를 만들고 입력받은 지역구분에 해당하는 지역구분상세 코드를 선택할 수 있게 했다.

document.addEventListener("DOMContentLoaded", function() {
    // 시/군 데이터를 저장한 객체
    const districtData = {
        "11": [
            { value: "11680", text: "강남구" },
            { value: "11740", text: "강동구" },
            { value: "11305", text: "강북구" },
            { value: "11500", text: "강서구" },
            { value: "11620", text: "관악구" },
            { value: "11215", text: "광진구" },
            { value: "11530", text: "구로구" },
            { value: "11545", text: "금천구" },
            { value: "11350", text: "노원구" },
            { value: "11320", text: "도봉구" },
            { value: "11230", text: "동대문구" },
            { value: "11590", text: "동작구" },
            { value: "11440", text: "마포구" },
            { value: "11410", text: "서대문구" },
            { value: "11650", text: "서초구" },
            { value: "11200", text: "성동구" },
            { value: "11290", text: "성북구" },
            { value: "11710", text: "송파구" },
            { value: "11470", text: "양천구" },
            { value: "11560", text: "영등포구" },
            { value: "11170", text: "용산구" },
            { value: "11380", text: "은평구" },
            { value: "11110", text: "종로구" },
            { value: "11140", text: "중구" },
            { value: "11260", text: "중랑구" }
        ],
        "26": [
            { value: "26440", text: "강서구" },
            { value: "26410", text: "금정구" },
            { value: "26710", text: "기장군" },
            { value: "26290", text: "남구" },
            { value: "26170", text: "동구" },
            { value: "26260", text: "동래구" },
            { value: "26230", text: "부산진구" },
            { value: "26320", text: "북구" },
            { value: "26530", text: "사상구" },
            { value: "26380", text: "사하구" },
            { value: "26140", text: "서구" },
            { value: "26500", text: "수영구" },
            { value: "26470", text: "연제구" },
            { value: "26200", text: "영도구" },
            { value: "26110", text: "중구" },
            { value: "26350", text: "해운대구" }
        ],
	    "27": [
	        { value: "27200", text: "남구" },
	        { value: "27290", text: "달서구" },
	        { value: "27710", text: "달성군" },
	        { value: "27140", text: "동구" },
	        { value: "27230", text: "북구" },
	        { value: "27170", text: "서구" },
	        { value: "27260", text: "수성구" },
	        { value: "27110", text: "중구" }
	    ]
		//이런식으로 쭉....
	};

 

시/도 리스트
시/군 리스트

 

설정해둔 값들을 저장했다가 나중에 공공데이터 API 호출할 때 사용해야겠다 생각하고 값을 정했다.

 

// 시/도 선택 시 시/군 목록 업데이트
document.getElementById("citySelect").addEventListener("change", function () {
    const selectedCity = this.value;
    const districtSelect = document.getElementById("districtSelect");

    console.log("Selected city code:", selectedCity); // 선택된 시/도 코드 출력

    // 시/군 옵션 초기화
    districtSelect.innerHTML = '<option value="">시/군</option>';

    // 시/군 데이터가 있는 경우에만 옵션 추가
    if (districtData[selectedCity]) {
        districtData[selectedCity].forEach(district => {
            const option = document.createElement("option");
            option.value = district.value;
            option.textContent = district.text;
            districtSelect.appendChild(option);
        });
        districtSelect.disabled = false; // 활성화
        console.log("Districts updated for city:", selectedCity); // 시/군 리스트 업데이트 확인
    } else {
        districtSelect.disabled = true; // 비활성화
        console.log("No districts available for city:", selectedCity); // 해당 시/도에 시/군이 없는 경우
    }
});

 

 

 


 

 

지역코드, 상세지역코드로 API 호출하기

 

 

이렇게 시/도 선택시 시/군 목록이 업데이트 되게 했고

 

이렇게 받은 값들을 검색하기 버튼 클릭 시 API 호출될 때 사용하게 했다.

지역 선택 후 검색하기

 

충전타입은 아직 체크박스만 만들어놨고 추후에 선택한 타입에 따라 API가 호출되게 변경할 예정!

이렇게 검색한 값들은 검색결과 밑에 리스트 형식으로 나오게 했다.

// 검색하기 버튼 클릭 시 API 호출
document.getElementById("stationSearchButton").addEventListener("click", function () {
    const cityCode = document.getElementById("citySelect").value;
    const districtCode = document.getElementById("districtSelect").value;

    console.log("City Code:", cityCode); // 시/도 코드 확인
    console.log("District Code:", districtCode); // 시/군 코드 확인

    if (!cityCode || !districtCode) {
        alert("시/도와 시/군을 선택해 주세요.");
        return;
    }

    const apiKey = "서비스 키";
    const apiUrl = `http://apis.data.go.kr/B552584/EvCharger/getChargerInfo?serviceKey=${encodeURIComponent(apiKey)}&numOfRows=10&pageNo=1&dataType=XML&zcode=${cityCode}&zscode=${districtCode}`;
    console.log("API URL:", apiUrl); // API URL 확인

    fetch(apiUrl)
        .then(response => {
            console.log("API Response Status:", response.status); // API 응답 상태 확인
            if (!response.ok) {
                throw new Error("API 호출 오류");
            }
            return response.text();
        })
        .then(data => {
            console.log("API Data Received:", data); // API로 받은 데이터 확인
            const parser = new DOMParser();
            const xmlDoc = parser.parseFromString(data, "application/xml");
            const items = xmlDoc.getElementsByTagName("item");
            console.log("Number of items received:", items.length); // 받은 item 수 확인

            const resultList = document.querySelector(".searchlist ul");
            resultList.innerHTML = ""; // 기존 리스트 초기화

            for (let i = 0; i < items.length; i++) {
                const statNm = items[i].getElementsByTagName("statNm")[0].textContent;
                const addr = items[i].getElementsByTagName("addr")[0].textContent;
                const useTime = items[i].getElementsByTagName("useTime")[0].textContent;
                const output = items[i].getElementsByTagName("output")[0].textContent;
                const type = items[i].getElementsByTagName("chgerType")[0].textContent;

                console.log(`Item ${i + 1}:`, { statNm, addr, useTime, output, type }); // 각 item 정보 확인

                const chargerTypeMap = {
                    "01": "DC차데모",
                    "02": "AC완속",
                    "03": "DC콤보",
                    //... 이런식으로 추가하기!
                };
                const typeText = chargerTypeMap[type] || "알 수 없는 타입";

                const listItem = document.createElement("li");
                listItem.className = "search-item";
                listItem.innerHTML = `
                    <div class="info">
                        <h3>${statNm}</h3>
                        <p>${addr}</p>
                        <div class="status">
                            <span class="available">사용가능</span>
                            <span class="fast">⚡ ${output}kW</span>
                            <span class="type">타입: ${typeText}</span>
                        </div>
                        <p>이용시간: ${useTime}</p>
                    </div>
                `;
                resultList.appendChild(listItem);
            }
        })
        .catch(error => console.error("API 호출 오류:", error));
});

 

api 호출 결과

 

 

이런식으로 잘 가져온다! 지금은 테스트 겸 1페이지의 10개의 값만 가져오고 있다.

앞으로 더 추가할 기능은

모든 충전소 값들을 가져오고, 타입 부분도 더 추가해서 어떤 충전기 타입인지 추가,

css 추가해서 스크롤로 모든 값들 확인할 수 있게 변경

충전타입에 따른 검색결과 가져오기,

리스트에 나온 충전소들 지도에 모두 라벨로 표시하고 라벨 클릭시 해당 충전소에 대한 자세한 정보 팝업

정도면 될 것 같다!