화면 위에 카카오 맵 API 사용해서 webview 형식으로 불러오는 거 까지 성공한 상태에서 추가 작업하기!
상단에 버튼을 두고 버튼 누를 시
javascript로 공공데이터포털에서 제공하는 전기차 충전소 제공 API를 사용해보려고 했다.
☑️ 충전소 찾기 버튼 + 드롭다운 리스트
일단 상단에 주변 충전소 찾기 라는 버튼을 하나 두고
버튼을 클릭 시 드롭다운 리스트가 나오게 했고
사용자가 시/도 선택시 시/군을 선택 할 수 있는 리스트가 활성화되게 했다.
각각 시/도와 시/군에는 value값을 둬서 전기차 충전소 API를 호출할 때 사용할 수 있게 했다.
충청남도에 해당하는 value 44를 선택하게 되면 cityDistricts에서 값을 가져온다.
여기서 다음 드롭다운이 활성화되면서 시/군이 사용자한테 보여지고,
천안을 선택하면 value: 44130이 api호출시에 사용되게 된다.
const cityDistricts = {
...
"44": [
{ value: "44250", text: "계룡시" },
{ value: "44150", text: "공주시" },
{ value: "44710", text: "금산군" },
{ value: "44230", text: "논산시" },
{ value: "44270", text: "당진시" },
{ value: "44180", text: "보령시" },
{ value: "44760", text: "부여군" },
{ value: "44210", text: "서산시" },
{ value: "44770", text: "서천군" },
{ value: "44200", text: "아산시" },
{ value: "44810", text: "예산군" },
{ value: "44130", text: "천안시" },
{ value: "44790", text: "청양군" },
{ value: "44825", text: "태안군" },
{ value: "44800", text: "홍성군" }
],
...
}
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={toggleDropdown}>
<Text style={styles.buttonText}>주변 충전소 찾기</Text>
</TouchableOpacity>
</View>
{/* 현재 위치로 이동하는 아이콘 버튼 */}
<TouchableOpacity style={styles.locationButton} onPress={handleMoveToCurrentLocation}>
<Icon name="my-location" size={24} color="black" />
</TouchableOpacity>
{dropdownVisible && (
<View style={styles.dropdownContainer}>
<Text style={styles.dropdownTitle}>시/도 선택</Text>
<Picker
selectedValue={selectedCity}
style={styles.picker}
onValueChange={(value) => {
setSelectedCity(value);
setSelectedDistrict(''); // 시/도 변경 시 시/군 초기화
}}
>
<Picker.Item label="시/도" value="" />
<Picker.Item label="서울특별시" value="11" />
<Picker.Item label="부산광역시" value="26" />
<Picker.Item label="대구광역시" value="27" />
<Picker.Item label="인천광역시" value="28" />
<Picker.Item label="광주광역시" value="29" />
<Picker.Item label="대전광역시" value="30" />
<Picker.Item label="울산광역시" value="31" />
<Picker.Item label="세종특별자치시" value="36" />
<Picker.Item label="경기도" value="41" />
<Picker.Item label="충청북도" value="43" />
<Picker.Item label="충청남도" value="44" />
<Picker.Item label="전북특별자치도" value="52" />
<Picker.Item label="전라남도" value="46" />
<Picker.Item label="경상북도" value="47" />
<Picker.Item label="경상남도" value="48" />
<Picker.Item label="제주특별자치도" value="50" />
<Picker.Item label="강원특별자치도" value="51" />
</Picker>
<Text style={styles.dropdownTitle}>시/군 선택</Text>
<Picker
selectedValue={selectedDistrict}
style={styles.picker}
onValueChange={(value) => setSelectedDistrict(value)}
enabled={selectedCity !== ''}
>
<Picker.Item label="시/군" value="" />
{getDistrictsByCity(selectedCity).map((district) => (
<Picker.Item key={district.value} label={district.text} value={district.value} />
))}
</Picker>
<TouchableOpacity style={styles.searchButton} onPress={handleSearch}>
<Text style={styles.searchButtonText}>검색</Text>
</TouchableOpacity>
</View>
이렇게 해서 검색 버튼을 누르면 해당하는 선택된 시/군과 시/도에 해당하는 value값을 api호출시에 전달해서
해당하는 지역의 전기차 충전소의 정보를 가지고 오는게 목적!
그러고 기존에 웹에서 사용하던 api호출 부분을 가져왔다.
테스트 겸 충전소 이름, 주소, 위도와 경도를 가져왔다.
위도 경도로는 마커를 표시하는데 사용했고 마커를 클릭 시 충전소 이름,주소가 뜨게 했다.
api 호출 시
zcode에 해당하는 값은 selectedCity에서 가져오게 했고,
zscode에 해당하는 값은 selectedDistrict에서 가져오게 했다.
그러면 최종적으로 시/도 → 시/군에 해당하는 API가 호출되는게 목적!
테스트니까 numOfRows=100, pageNo=1!
const apiKey = "공공데이터 API 키";
const apiUrl = `http://apis.data.go.kr/B552584/EvCharger/getChargerInfo?serviceKey=${encodeURIComponent(apiKey)}&numOfRows=100&pageNo=1&dataType=JSON&zcode=${selectedCity}&zscode=${selectedDistrict}`;
try {
const response = await fetch(apiUrl);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.json();
if (data.items && data.items.item) {
const chargerData = data.items.item.map((charger) => ({
name: charger.statNm,
address: charger.addr,
lat: parseFloat(charger.lat),
lng: parseFloat(charger.lng),
}));
setChargers(chargerData);
addMarkersToMap(chargerData);
} else {
console.log("충전소 데이터를 찾을 수 없습니다.");
}
} catch (error) {
console.error("Error fetching data:", error);
}
};
상단에 충전소 정보의 배열들을 저장할 useState배열도 추가하고
const [chargers, setChargers] = useState([]);
마커를 추가할 addMarkersToMap도 추가했다.
또한 추가된 마커를 클릭할 때 charger값에 저장해둔 name, address도 표시하게 하고 테스트!
콘솔에도 값 찍어보기!
const addMarkersToMap = (chargers) => {
if (webViewRef.current) {
// 모든 마커의 위치를 포함할 수 있도록 bounds 객체 생성
const boundsJS = chargers.map((charger) => `
new kakao.maps.LatLng(${charger.lat}, ${charger.lng})
`).join(',');
const markersJS = chargers.map((charger) => `
(function() {
const position = new kakao.maps.LatLng(${charger.lat}, ${charger.lng});
const marker = new kakao.maps.Marker({
position: position,
map: map,
title: '${charger.name}'
});
kakao.maps.event.addListener(marker, 'click', function () {
const infoContent = '<div><h3>${charger.name}</h3><p>${charger.address}</p></div>';
const infoWindow = new kakao.maps.InfoWindow({ content: infoContent });
infoWindow.open(map, marker);
});
})();
`).join('\n');
console.log("Markers JS:", markersJS);
webViewRef.current.injectJavaScript(`
(function() {
const bounds = new kakao.maps.LatLngBounds();
[${boundsJS}].forEach((position) => bounds.extend(position));
// 마커 추가
${markersJS}
map.setBounds(bounds);
})();
`);
}
};
테스트 결과
잘 불러와지는거 같다.
지도에 마커가 찍히면서 마커들이 다 나오는지, 마커를 눌렀을 때 해당 충전소의 값들이 나오는지 테스트!
잘 불러와진다!
이제 테스트로 찍은 name, adress, lat, lng 말고도 추가 값들을 가져와서 마커 클릭 시 보여지게 하고
//값 더 추가하기
name: charger.statNm,
address: charger.addr,
lat: parseFloat(charger.lat),
lng: parseFloat(charger.lng),
...
충전소 팝업 부분 css 후
길 찾기 기능을 넣으면 될 것 같다.
길 찾기 기능은 카카오 모빌리티 API 사용하면 될 것 같다! 웹에서 해봤으니까!
☑️ 내 위치 버튼 + 마커 추가
추가적으로 좌측 하단에 내 위치 아이콘을 넣어서
내 위치로 이동하게 하면서 마커가 찍히게 추가!
react-native-vector-icons 라이브러리를 사용했다.
import Icon from 'react-native-vector-icons/MaterialIcons';
const handleMoveToCurrentLocation = () => {
if (webViewRef.current) {
const jsCode = `
(function() {
const position = new kakao.maps.LatLng(${location.latitude}, ${location.longitude});
map.setCenter(position);
map.setLevel(4);
const marker = new kakao.maps.Marker({
position: position,
map: map,
});
})();
`;
webViewRef.current.injectJavaScript(jsCode);
}
};
{/* 현재 위치로 이동하는 아이콘 버튼 */}
<TouchableOpacity style={styles.locationButton} onPress={handleMoveToCurrentLocation}>
<Icon name="my-location" size={24} color="black" />
</TouchableOpacity>
추가적으로 해야 할 것들
1. 100개로 가져오고 있는 부분을 페이지네이션이나 다른 방법으로 계속 새로 가져올 수 있게 추가
2. 길 찾기 기능 추가
3. 충전소 결과에 해당하는 마커 클릭 시 충전소 정보 팝업 제공
4. 충전소 정보 팝업에 길 찾기 버튼 추가 및 길 찾기 버튼 클릭 시 도착지로 위도,경도 넘기기
5. 현재 위치에 해당하는 위도,경도를 길 찾기 기능의 출발지로 넘기기
6. 길 찾기 버튼 클릭 시 나오는 네비게이션 정보 가공(1000m 이상 단위 1km로, 좌,우회전 등등 스타일링)
7. 같은 방식으로 주차장, 기름 페이지 추가
8. 최초 앱 접속시 메인페이지
일단 이정도만 하면.. 진행하는 프로젝트랑 비슷하게 구현할 수 있을 거 같다!
웹으로 한 작업들을 다시 앱으로 변환하고 있어서 어떤 걸 해야할지는 바로바로 정할 수 있지만
RN언어랑 학원에서 배우고 있는 JSP나 JPA랑은 달라서 많이 어렵다!
1차 프로젝트를 리액트로 했지만 그땐 아무것도 모르고 들이박았던 수준이라 새로 배우는 마음으로 하는중,,
3차 프로젝트 끝낼 때 까지 웹과 앱 두개를 다 할 수 있을지 모르겠지만
일단 해봐야지!!!
'Develop > ReactNative' 카테고리의 다른 글
네이티브 환경설정 + 카카오 맵 (1) | 2024.11.10 |
---|---|
네이티브 살짝 건드려보기 (4) | 2024.11.09 |
RN의 앱 로그인 과정 + DB연동 (3) (2) | 2024.09.10 |
하면 할수록 어렵지만 쉬운(?) RN.. (2) (0) | 2024.09.08 |
ReactNative 공부 시작! (1) (1) | 2024.09.07 |