지오코딩
지오코딩은 람이 읽을 수 있는 주소를 지도상의 위치로 변환하는 과정이다. 우리가 보통 쓰는 글로 된 주소를 입력하면 위도와 경도로 변환한다. 여기서는 지오코딩 API인 Mapbox를 사용하기 때문에 Mapbox에 접속해서 회원가입을 한다.
설치
Mapbox에는 mapbox-sdk라는 Node 클라이언트가 있어서 npm으로 설치하면 된다.
npm install @mapbox/mapbox-sdk
실습
환경변수 설정
회원가입하고 어카운트에 들어가면 access token이 있다. 그것을 복사해서 .env에 아래의 등호 옆에 붙여 넣는다.
MAPBOX_TOKEN=
Mapbox 설정
아래 코드를 boilerplate.ejs에 붙여 넣는다. mapbox api를 사용하기 위한 스크립트다.
<script src='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.css' rel='stylesheet' />
함수를 정의해 놓은 campground.js 파일에서 아래와 같이 선언을 한다.
const mbxGeocoding = require('@mapbox/mapbox-sdk/services/geocoding');
const mapBoxToken = process.env.MAPBOX_TOKEN;
const geocoder = mbxGeocoding({ accessToken: mapBoxToken });
경도, 위도 검색
아래 코드를 한번 실행하면 뭐가 많이 나오는데 우리가 필요한 건 body 부분이다.
const geoData = await geocoder.forwardGeocode({
query: '대구광역시', // 검색할 주소
limit: 1 // 검색 결과 개수
}).send();
console.log(geoData)
이번엔 features를 출력해 보자. geometry의 coordinates에는 경도와 위도가 적혀있다. geometry를 campground 스키마에 저장한다.
DB 수정
campground 스키마에 아래 코드를 추가한다. geometry의 타입은 Point 여야 하며, coordinates는 순서대로 경도와 위도 정보가 적혀있다.
geometry: {
type: {
type: String,
enum: ['Point'],
required: true
},
coordinates: {
type: [Number],
required: true
}
}
캠핑장 생성&수정
캠핑장을 생성할 때 입력받은 location 정보로 geometry를 가져온다. features가 배열이고, 배열에 검색 결과가 하나 담겨있기 때문에 features[0]이라 한다. 캠핑장 수정 함수에도 동일한 코드를 추가하면 된다.
const geoData = await geocoder.forwardGeocode({
query: req.body.campground.location,
limit: 1
}).send();
camp.geometry = geoData.body.features[0].geometry;
지도 표시하기
캠핑장의 상세 페이지인 show 페이지에 들어가면 지도를 보여주게 해보자.
먼저 아래 코드를 표시하길 원하는 위치에 삽입한다.
<div id='map' style='width: 100%; height: 300px; '></div>
최하단에서 Mapbox의 토큰을 정의하고, Mapbox 지도를 표시하기 위한 스크립트 파일을 포함시킨다.
const campground = <%- JSON.stringify(camp) %>;는 showPageMap.js에서 현재 캠핑장에 접근할 수 있도록 해준다.
<script>
const mapToken = '<%-process.env.MAPBOX_TOKEN%>';
const campground = <%- JSON.stringify(camp) %>;
</script>
<script src="/javascript/showPageMap.js"></script>
showPageMap.js의 코드이다. 지도가 보이게 할 때 중심을 center: campground.geometry.coordinates으로 설정한다.
아래 new mapboxgl.Marker() 코드는 지정한 위치에 핑을 찍어준다. setPopup으로 핑을 클릭하면 캠핑장의 이름과 장소를 팝업으로 띄워준다.
mapboxgl.accessToken = mapToken;
const map = new mapboxgl.Map({
container: 'map', // container ID
style: 'mapbox://styles/mapbox/light-v10', // style URL
center: campground.geometry.coordinates,
zoom: 9, // starting zoom
});
new mapboxgl.Marker()
.setLngLat(campground.geometry.coordinates)
.setPopup(
new mapboxgl.Popup({offset: 25})
.setHTML(
`<h3>${campground.title}</h3><p>${campground.location}</p>`
)
)
.addTo(map)
참고
show 페이지 최하단 부분
<script>
const mapToken = '<%-process.env.MAPBOX_TOKEN%>';
const campground = <%- JSON.stringify(camp) %>;
</script>
const campground = <%- JSON.stringify(camp) %>; 여기서 <%- %> 이거를 vscode가 인식을 못해서 한참 헤매다가 검색해서 해결 방법을 알았다.
이제 <%- %>는 인식한다.
근데 저장하면서 자동으로 format 맞춰주는 기능 때문에 <% - 으로 %랑 - 사이에 띄어쓰기가 들어간다.
그래서 저장 시 자동 띄워쓰기 해주는 기능도 껐다.
1. Ctrl + ,
2. Text Editor → Formatting
3. Format On Save 체크 해제
이제 정상적으로 작동된다.
'웹 프로그래밍' 카테고리의 다른 글
[Yelpcamp 프로젝트] 디자인 수정 (0) | 2023.12.10 |
---|---|
[Yelpcamp 프로젝트] 클러스터 맵 (0) | 2023.12.09 |
[Yelpcamp 프로젝트] 이미지 편집 (0) | 2023.12.07 |
[Yelpcamp 프로젝트] 이미지 파일 (1) | 2023.12.07 |
[Yelpcamp 프로젝트] 로그인 구현 (0) | 2023.12.01 |