개발일기장

React에서 GPS사용하기 watchPosition, getCurrentPosition 차이점 본문

React.js

React에서 GPS사용하기 watchPosition, getCurrentPosition 차이점

게슬 2021. 12. 24. 13:22
728x90

GPS가 잘 찍히는지 확인하기 위해서 지도는 Kakao Map API를 사용했고, view는 react를 사용해서 이동하는 것을 선으로 표시해봤다.

0. 시작

Javascript에서 GPS를 사용하기 위해서 geolocation API를 사용해야한다.

근대 거기서 getCurrentPosition이랑 watchPosition이 있고 상황에 따라서 원하는것을 사용하면 된다.

1. getCurrentPosition

이거는 자신이 원할 때 1회성으로 GPS의 snapshot을 볼 수 있는 방법

일단 코드부터 보면 이렇게 된다.

export function getLocation() {
    return new Promise((resolve, reject) => {
        if (navigator.geolocation) {
            const now = new Date();
            navigator.geolocation.getCurrentPosition(
                (position) => {
                    resolve({
                        err: 0,
                        time: now.toLocaleTimeString(),
                        latitude: position.coords.latitude,
                        longitude: position.coords.longitude,
                    });
                },
                (err) => {
                    resolve({
                        err: -1,
                        latitude: -1,
                        longitude: -1,
                    });
                },
                { enableHighAccuracy: true, maximumAge: 2000, timeout: 5000 }
            );
        } else {
            reject({ error: -2, latitude: -1, longitude: -1 });
        }
    });
}

일단 해당 브라우저가 navigato.geolocation을 지원하는지 확인을 한 다음.

getCurrentPosition(success, error, option)를 호출하면 된다. 

위치를 구할 수 있으면 success callback함수에 position이 반환되고 이걸로 위치정보를 확인할 수 있다.

위치 구하기가 실패하면 false가 나오고 error에 관한 정보를 얻을 수 있다.

option에서는 정확도, 뭐 이것저것 있는데 직접 찾아보셈(솔직히 요즘 기계가 좋아서인지 별 차이를 못느끼겠음.)

 

뭔가 맘에 안든다.

몇미터 이동할때마다 UPDATE를 해주는대도 내 위치가 완벽하게 측정되지 않는다.

파란색이 직접 걸어본거고, 빨간색이 찍힌건데 GPS위치가 5개 정도밖에 변하지 않았다.

이거 사용할 때는 원할때 마다 buttun event라던가 setTimeout처럼 직접 코드에서 함수를 호출해야 한다.

 

+추가적으로 사용하다 보니깐 일정시간동안 특정 위치에 있다가 위치를 확인하면 그 자리에서 볼 수 있더라고..

2. watchPosition (+clearWatch)

이거는 사용자가 움직이는 것을 계속 감시? 감지한다.

코드부터 보면 (React에서 작업했고, useState를 사용했음.) 이렇다.

if (navigator.geolocation) {
            let before_record = null;
            const newId = navigator.geolocation.watchPosition(
                (position) => {
                    let updateFlag = true;
                    const now = new Date();
                    const new_record = {
                        err: 0,
                        time: now.toLocaleTimeString(),
                        latitude: position.coords.latitude,
                        longitude: position.coords.longitude,
                    };
                    setcoords(new_record);
                },
                (err) => {
                    console.log(err.message);
                },
                { enableHighAccuracy: false, maximumAge: 10000, timeout: 5000 }
            );
            setRecording(true);
            setWatchId(newId);
        }

getCurrentLocation의 경우에는 원할때마다 계속 함수를 호출해 주어야 하지만.

watchPosition의 경우에는 한번 함수를 실행하면 직접 종료해주기 전까지 이동하는 위치를 다 알려준다.

파라미터의 경우에는 getCurrentLocation과 같다.

반환값은 정수형 id를 준다.

 

사용한 결과..

원하는대로 나온다.

 

근대 이건 너무 정밀도가 높아진 기분이 들었다. 대가리 방향만 돌려도 이동이 된것으로 감지를 한다.

모든 변화에 대해서 표시만 해주는게 아니라 추가적인 작업을 할 거면 좀 부하가 걸릴것 같더라.

 

watch를 중지하려면 clearWatch에 위에서 얻은 id를 집어넣어주면 된다.

    const finishAutoRecordButtonListener = (e) => {
        e.preventDefault();
        if (watchId !== -1) {
            navigator.geolocation.clearWatch(watchId);
            setWatchId(-1);
        }
    };

그러면 끝.

2-1 watchPosition 추가

근대 내가 처음 색각하던거에서 너무 정밀도가 높으면 처리해야할 일이 많아지고, 너무 낮으면 하는 이유가 사라진다.

그래서 이전 거리와 50m이상 변경이 감지되는 경우에만 이동이 처리되도록 했다.

 

일단 GPS가 위도 경도로 값이 나오므로 이것을 이용한 거리를 구해야 한다.

코드는 구글링해서 직접 찾아보셈 ^오^ 넘처남

    //자동 레코드
    const locationAutoButtenListener = (e) => {
        e.preventDefault();
        if (navigator.geolocation) {
            let before_record = null;
            const newId = navigator.geolocation.watchPosition(
                (position) => {
                    let updateFlag = true;
                    const now = new Date();
                    const new_record = {
                        err: 0,
                        time: now.toLocaleTimeString(),
                        latitude: position.coords.latitude,
                        longitude: position.coords.longitude,
                    };
                    //시작
                    if (before_record !== null) {
                        const dist = getDistance({
                            lat1: before_record.latitude,
                            lon1: before_record.longitude,
                            lat2: new_record.latitude,
                            lon2: new_record.longitude,
                        });
                        //이동거리가 50m미만이면 안바뀜
                        if(dist < 0.05){
                            updateFlag = false;
                        }
                    } 

                    if(updateFlag){
                        setcoords(new_record);
                        before_record = new_record;
                        setLocationList((locationList) => [
                            ...locationList,
                            new_record,
                        ]);
                    }
                },
                (err) => {
                    console.log(err.message);
                },
                { enableHighAccuracy: true, maximumAge: 10000, timeout: 5000 }
            );
            setRecording(true);
            setWatchId(newId);
        }
    };

콜백함수이고 이벤트 루프에 들어가게 되면 함수 밖을 참조하는 변경된 값을 저 함수 내부에서 확인할 수 없기 때문에

before_record 변수를 선언하고 이전에 측정된 좌표를 계속 저장해 주어야 한다.

그래서 지금측정된것, 이전에 측정된 것에 대한 좌표가 50m이상 차이가 나면 추가해주고 아니면 그냥 넘기는 방식으로 진행을 했다.

그 결과는 밑처럼 나온다.

만족스럽다

이제 이 데이터로 이것저것 해봐야겠다. 

개같은 취업준비하다가 졸업앞두고 이런거 만들니 재밌는듯?

 

 

전체 코드는 여기

https://github.com/tlqckd0/walk-history

 

GitHub - tlqckd0/walk-history

Contribute to tlqckd0/walk-history development by creating an account on GitHub.

github.com

 

728x90

'React.js' 카테고리의 다른 글

useState로 List 작업  (0) 2023.03.03
React에서 kakao map api사용하기  (0) 2021.12.23
Rechart 데이터 변경 (이것저것)  (0) 2021.07.14
Rechart Data 동적으로 추가  (0) 2021.07.12
Recharts simpleLineChart - type  (0) 2021.07.12
Comments