티스토리 뷰
주어진 상황
프로젝트에서 맡은일중 하나인 실시간 구조 요청이다.
유저 1, 유저 2, 유저 3이 존재한다고 가정한다.
유저 1이 도움이 필요한 상황이다.
당근에서 처럼 상황이 ~~한데 도와주세요 요청을 보낸다.
이 상황은 구급 • 긴급 상황은 아니지만 도움이 필요할때 사용하기 위한 기능이다.
즉, 119에 신고할만한 정도는 아니지만 혼자서는 해결할수 없는 정도의 일이라고 가정한다.
이때 유저 1이 sos버튼을 누르면 주변에 나를 도와줄 수 있는 유저를 찾아서 알려준다.
유저 2와 유저 3은 해당서비스에 등록된 사람이고 등록된 사람안에서 위치 기반서비스가 허용된 사람의 위치를 찾는다.
구현해야하는 기능
1. 개개인 유저들의 위치 정보를 저장
2. 구조 요청을 하는 유저의 위치를 기준으로 주변의 유저 탐색
3. 유저와 도와줄 사람의 위치의 최 단거리 표시
사용자 위치 기반서비스 api
Geolocation API
- 정확한 위치 정보를 제공
- GPS, Wi-Fi, IP주소 데이터의 조합을 활용하여 사용자의 위치를 확인
- 위도 및 경도 좌표와 같은 정확한 위치 정보를 제공
사용 예
→ Uber, Instagram, 날씨 애플리케이션, 배달 실시간 위치 등에서 주로 사용.
Geolocation API의 종류
- 웹 브라우저에서 제공되는 Geolocation API
- Google Maps API
- Mapbox API
- OpenStreetMap(OSM)
- TomTom - Geolocation API
- HEAR API
Geolocation API를 선택한 이유
여기에서 이미 플랫폼에서 만든 API를 사용하여도 되지만 기본적인 위치 기반 서비스와 기능만으로도 충분할것 같아
웹 브라우저에서 제공되는 Geolocation API를 사용하기로 하였다.
기능 구현 (JavaScript)
사용자의 위치 정보 가져오기
일단 가장 중요한 나의 위치부터 가져올수 있는지 확인해 보았다.
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
navigator.geolocation.getCurrentPosition(async function (pos) {
console.log(pos);
var latitude = pos.coords.latitude;
var longitude = pos.coords.longitude;
let location = {
latitude,
longitude,
timestamp: new Date(),
};
await addDoc(collection(db, "location"), location);
navigator.geolocation.getCurrentPosition
- 현재 사용자의 위치를 요청함
- 위치가 뜨는 곳과 실제 위치한곳과 얼마나 가까운지의 수치, 현재 위치의 경도, 위도가 담겨있다.
지금 구하려는건 적어도 최소 두사람의 위치를 받아와야 한다.
그래야 구조 신호를 위한 거리를 체크를 할수가 있다.
일단 파이어 스토어에 정보를 저장하여 테스트 해보았다.
또한 간단하게 깃허브페이지로 배포하여 해당 링크로 접속한 유저들의 정보를 받아왔다.
이렇게 모바일 하나 데스크탑 하나로 두개의 위치를 받아오는데 성공하였다.
모바일 기기에는 GPS 칩셋 및 다양한 센서가 내장되어 있어서 보다 정확한 위치 결정이 가능.
반면에 데스크탑 컴퓨터는 GPS가 내장되어 있지 않으며,
위치 정보를 결정하기 위해서는 외부 기기(예: IP주소 , Wi-Fi 라우터, 인터넷 서비스 제공자 등)에 의존해야 한다.
그렇기 때문에 같은 위치지만 차이가 발생한다.
position객체의 속성
getCurrentPosition의 첫번째 매개변수인 익명함수에 pos라는 매개변수가 들어가는데 여기에는 position객체가 들어간다.
메서드 | 속성 |
position.coords.latitude | 위도 |
position.coords.longitude | 경도 |
position.timestamp | 위도경도 취득 날자 |
position.coords.accuracy | 현재 위치의 정확도 |
position.coords.heading | 방위(도) |
position.coords.speed | 속도 |
두 사람의 거리 계산
이제 우리는 이 두 위치를 사용하여 서로의 위치를 파악해야 한다.
function distance(lat1, lon1, lat2, lon2) {
const R = 6371; // 지구 반지름 (단위: km)
const dLat = deg2rad(lat2 - lat1);
const dLon = deg2rad(lon2 - lon1);
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = R * c; // 두 지점 간의 거리 (단위: km)
const finalDistance = Number(distance.toFixed(1));
console.log("distance => ", finalDistance);
return finalDistance;
}
function deg2rad(deg) {
return deg * (Math.PI / 180);
}
하버사인 공식 - 최단 거리 구하기
쉽게 말해 단순 직선거리를 구하는것이아닌 지구는 둥글기 때문에 그에 맞게 거리를 계산해줘야한다.
그렇기 때문에 단순 계산이 아닌 곡선에 대한 계산을 해서 맞춰 주어야 한다.
하버사인 공식을 사용하지 않고
두지점 간의 직선거리를 단순하게 계산하려면 직선 거리를 구하는 유클리드 거리 공식을 사용하면된다.
좌표 평면상의 두점 간의 직선 거리를 계산하는 공식이다.
임의의 위도 경도를 2개씩 주어졌을때 두 거리를 유클리드 거리공식과 하버사인공식으로 계산했을때 확연히 차이가 난다.
유클리드 거리공식
0.0020310358611020156 km
하버사인 공식
0.28707969654002624 km
결과 값이 확연히 달라진다.
카카오 맵 기준으로 비교해보면
하버사인 공식이 거의 근접해있다는걸 알수가 있다.
그렇게 하버사인 공식을 사용하여 구조자와의 최단 거리를 알수가 있게 되었다.
테스트
참고자료
'project > sparta' 카테고리의 다른 글
[최종 프로젝트]실시간 구조 요청 보내기3 (위치 기반 서비스) (0) | 2024.04.14 |
---|---|
[최종 프로젝트]실시간 구조 요청 보내기2 (위치 기반 서비스) (0) | 2024.04.11 |
[최종 프로젝트] Puppeteer 크롤링하기2<문자열 유사성 알고리즘> (0) | 2024.04.05 |
[최종 프로젝트] Puppeteer 크롤링하기 1 (0) | 2024.04.03 |
[최종 프로젝트] 개발일정 논의 및 기술 결정 (0) | 2024.03.28 |