페어 활동 기록_Day11_한빈_상준 - boostcampwm-2022/web33-Mildo GitHub Wiki
✂️ 분배된 이슈
- 네이버 지도 API 연결
- 지도 초기 화면을 서울 중심으로 출력
🚩 구현 목표
- 사용자가 모바일 환경에서 네이버 지도 화면을 확인할 수 있어야 함
- 기존 이슈를 적절하게 나눠서 세부 목표 작성
- branch name : feature/map
🍀 세부 목표
Mildo에 네이버 지도 API 가져와서 보여주기(#5)
- typescript 타입 설정을 위한 @types/navermaps 설치
- 맵 관련 컴포넌트 생성
- 맵을 그릴 DOM 요소 생성
- map 옵션 설정하기(위치, 줌 등)
- DOM에 네이버 지도 그려주기
- 컴포넌트 렌더링 확인
MainPage 컴포넌트를 생성하고, 내부에 Map 컴포넌트 넣기(#10)
- pages 디렉토리 및 MainPage.tsx 파일 생성
- MainPage에 Map 컴포넌트 넣기
- 반응형 스타일링 적용
사용자 위치에 따른 지도 초기 화면 설정(#11)
- 브라우저에서 사용자 위치 정보 허용 요청
- 지도 초기 화면이 서울 중심지인 경우
- 사용자가 위치 정보 거부했을 때
- 사용자의 위치가 서울 이외의 지역일 때
- 지도 초기 화면이 사용자 위치인 경우
- 사용자의 위치가 서울일 때
- 지도 사용 가능 범위 서울로 제한
- 서울 이외의 지역으로 이동 금지
- 줌 기능 제한 걸기
🖥️ 구현 내용
Mildo에 네이버 지도 API 가져와서 보여주기(#5)
- CRA로 작성된 불필요한 파일 삭제
- createRoot로 index.tsx 리팩토링
- App.tsx에 전역 스타일 적용
- styled-components의 createGlobalStyle 사용
- 프로젝트 전체의 기본 margin과 padding을 0으로 설정
MainPage 컴포넌트를 생성하고, 내부에 Map 컴포넌트 넣기(#10)
- MainPage에 반응형 디자인을 위한 width, height 적용
- width에는 vw, height에는 vh 사용
- 자식 컴포넌트인 Map은 width, height 모두 100%로 설정
사용자 위치에 따른 지도 초기 화면 설정(#11)
- Map.tsx에서 react-hook-geolocation 라이브러리로 사용자 위치의 위·경도 확인
- 브라우저 접속 시 위치 정보 허용에 대한 팝업이 나타남
- 허용 시 사용자 위치의 위·경도를 확인 할 수 있음
- 서울일 경우 useState로 관리
- 서울이 아니거나 거부할 경우 서울 중심지를 기본 값으로 보여줌
- 현재 서울 중심지 기본 값 : 126.9769, 37.5656
- 참고 사이트 : https://www.npmjs.com/package/react-hook-geolocation
- 네이버 지도 API의 Reverse Geocoding으로 사용자 거주 지역(시군구) 확인
- Reverse Geocoding은 위·경도를 사용해 사용자의 구체적인 거주 지역을 확인할 수 있음
- 서울일 경우와 서울이 아닌 경우를 나눠서 처리
📖 학습 내용
네이버 지도 API Reverse Geocoding 사용 방법
-
네이버 지도 API에서 Reverse Geocoding 사용 요청
-
네이버 지도 URL로 get API 요청을 보냄
// 입력 좌표 coords=128.12345,37.98776 // 다른 파라미터는 공식 페이지 참고 const url = `https://naveropenapi.apigw.ntruss.com/map-reversegeocode/v2/gc ?coords={입력_좌표}&sourcecrs={좌표계}&orders={변환_작업_이름}&output={출력_형식}`; axios.get(url, headers : { // 앱 등록 시 발급받은 Client ID X-NCP-APIGW-API-KEY-ID:{Client ID} // 앱 등록 시 발급 받은 Client Secret X-NCP-APIGW-API-KEY:{Client Secret} }); -
요청 결과의 JSON 데이터에서 사용자의 지역을 확인
{ "status": { "code": 0, "name": "ok", "message": "done" }, "results": [ { "name": "roadaddr", "code": { "id": "1114016700", "type": "L", "mappingId": "09140167" }, "region": { "area0": { "name": "kr", "coords": { "center": { "crs": "", "x": 0.0, "y": 0.0 } } }, "area1": { "name": "서울특별시", "coords": { "center": { "crs": "EPSG:4326", "x": 126.9783882, "y": 37.5666103 } }, "alias": "서울" }, "area2": { "name": "중구", "coords": { "center": { "crs": "EPSG:4326", "x": 126.997602, "y": 37.563843 } } }, "area3": { "name": "정동", "coords": { "center": { "crs": "EPSG:4326", "x": 126.972925, "y": 37.5664 } } }, "area4": { "name": "", "coords": { "center": { "crs": "", "x": 0.0, "y": 0.0 } } } }, "land": { "type": "", "number1": "101", "number2": "", "addition0": { "type": "building", "value": "시청역 1호선" }, "addition1": { "type": "zipcode", "value": "04519" }, "addition2": { "type": "roadGroupCode", "value": "111402005001" }, "addition3": { "type": "", "value": "" }, "addition4": { "type": "", "value": "" }, "name": "세종대로", "coords": { "center": { "crs": "", "x": 0.0, "y": 0.0 } } } } ] } -
참고 사이트
- 네이버 지도 API Reverse Geocoding 공식 문서 : https://api.ncloud-docs.com/docs/ai-naver-mapsreversegeocoding-gc
‘openweathermap’으로 Reverse Geocoding 구현
- 지도 URL로 get API 요청을 보냄
https://naveropenapi.apigw.ntruss.com/map-reversegeocode/v2/gc?coords=${geolocation.latitude},${geolocation.longitude}&sourcecrs=epsg:4326&orders=roadaddr&output=json
- console에서 사용자의 거주 지역을 영어로 받아온 것을 확인

🚧 Trouble Shooting
Mildo에 네이버 지도 API 가져와서 보여주기(#5)
-
문제 1
-
원인 : ‘new’를 사용하여 새로운 인스턴스를 생성하였으나, 변수에 할당하지 않아 에러 발생
- Map 컴포넌트의 Dom에 네이버 지도를 그려주기 위해서는 해당 문법을 사용하는데, 변수에 할당할 필요는 없었음
[eslint] src\components\Map.tsx Line 29:5: Do not use 'new' for side effects no-new Search for the keywords to learn more about each error. ERROR in [eslint] src\components\Map.tsx Line 29:5: Do not use 'new' for side effects no-new Search for the keywords to learn more about each error. webpack compiled with 1 error No issues found. -
해결 방법 : 즉시 실행 함수로 ‘new’ 키워드를 사용함과 동시에 할당되지 않도록 설정
(() => new naver.maps.Map(mapRef.current, mapOptions))();
-
-
문제 2
-
원인 : null에 해당 타임을 할당할 수 없다는 에러 발생
ERROR in src/components/Map.tsx:29:31 TS2345: Argument of type 'null' is not assignable to parameter of type 'string | HTMLElement'. 27 | // if (!mapRef.current || !naver) return; 28 | > 29 | (() => new naver.maps.Map(mapRef.current, mapOptions))(); | ^^^^^^^^^^^^^^ 30 | }, []); 31 | 32 | return <MapComponent ref={mapRef} />; -
해결 방법 : 조건문을 사용해서 해당 변수가 null인 경우 리턴
- let으로 할당하는 경우가 있으나 데이터의 무결성 문제로 사용하지 않음
-
사용자 위치에 따른 지도 초기 화면 설정(#11)
- 문제 1
- 원인 : client에서 네이버 지도 API Reverse Geocoding 요청 시 CORS 에러 발생
- 네이버 지도 API는 보안을 위해 client에서 API 요청 시 의도적으로 에러를 발생 시킴
- 참고 사이트 : [https://velog.io/@ssong/Naver-Geocoding-API-CORS-에러-해결](https://velog.io/@ssong/Naver-Geocoding-API-CORS-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0)
- 해결 방법 1
- openweathermap으로 구현할 시 client에서 Reverse Geocoding 요청을 할 수 있음
- 그러나 외국 사이트여서 그런지 속도가 현저하게 느림
- 해결 방법 2
- server에서 네이버 지도 API 관련 router를 만들어서 사용
- 속도는 빠르나 결국 CORS 에러 처리를 해줘야 함
- 결론
- 네이버 지도 API를 계속해서 사용하기
- 제공하는 기능이 많아 서비스가 확대될 때 용이
- 속도가 빠름
- 한 달에 300만회까지는 Reverse Geocoding API 요청이 무료임
- 원인 : client에서 네이버 지도 API Reverse Geocoding 요청 시 CORS 에러 발생
🎸 기타
- 네이버 지도 API에서 지도 이동을 서울로 제한하는 방법
- 지도 이동 제한을 좌표 값으로 구현하는 방법
- Custom hook 사용법 익히기