ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 간호사 업무 해소 환자 위치 찾기 프로젝트 (1. Geolacation API )
    학원 프로젝트 2023. 5. 26. 13:50

    1. 프로젝트 개요

    학원에서 2번째 과제로 라즈베리파이를 이용한 간호사 업무 해소 기능을 만들기로 했다.

    환자의 위치를 추적할 수 있으면, 간호사가 환자를 찾는 수고를 덜 수 있고

    코로나 바이러스 처럼 전염 위험이 높은 병을 가진 환자를 관리할 수 있을 것이다.

     

    결론부터 말하자면 라즈베리 파이의 GPS와 블루투스 이용하는 것이 잘 되지 않았고

    라즈베리 파이를 적극적으로 활용하기 위해 flask 프레임워크를 제작하고 pythonanywhere에서 실행하고 싶었는데

    이 부분에도 많은 문제가 발생했다.

    eclipse의 spring legacy project로 Geolocation API와 Kakao Map API를 사용해서 환자의 위치를 실시간으로 확인할 수 있는 기능을 만들었다.

     

    이 글에서 eclipse로 구현한 기능을 소개하고, 다른 게시글에 라즈베리파이와 flask 이용 과정에서 발생했던 문제점을 정리해 보려고 한다.

     

    2. 기능

    2 - 1. Geolocation API

    먼저, 관찰 대상이 될 환자의 위치정보를 DB에 저장하기 위해 Geolocation API를 이용했다.

    환자가 자신의 이름과 핸드폰번호를 입력하고 추적 기능을 실행하면 현재 환자의 위도, 경도를 DB에 받는다

     

    $(function() {
        if (navigator.geolocation) {
          const saveLocation = function(latitude, longitude) {
            // 사용자 이름과 핸드폰 번호 가져오기
              const name = $('#name').val();
              const phone = $('#phone').val();
              
            // AJAX 요청을 통해 서버에 데이터 전송
            $.ajax({
              url: '/Geolocation', // 서버의 저장 로직을 처리하는 엔드포인트 URL
              method: 'POST',
              data: {
                name: name,
                phone: phone,
                x: latitude,
                y: longitude
         
              },
              success: function(response) {
                console.log('위치 정보가 성공적으로 저장되었습니다.');
              },
              error: function(xhr, status, error) {
                console.error('위치 정보 저장 중 오류가 발생했습니다:', error);
              }
            });
          };
      
          const getPosition = function() {
            navigator.geolocation.getCurrentPosition(
              function(pos) {
                const currentCoords = {
                  latitude: pos.coords.latitude,
                  longitude: pos.coords.longitude
                };
      
                $('#x').html(currentCoords.latitude);  // 위도 
                $('#y').html(currentCoords.longitude); // 경도 
      
                // 서버에 위치 정보 저장 요청
                saveLocation(currentCoords.latitude, currentCoords.longitude);
              },
              function(error) {
                // 오류 처리
                switch (error.code) {
                  case error.PERMISSION_DENIED:
                    alert("위치 정보 사용 권한이 거부되었습니다.");
                    break;
                  case error.POSITION_UNAVAILABLE:
                    alert("위치 정보를 사용할 수 없습니다.");
                    break;
                  case error.TIMEOUT:
                    alert("위치 정보 요청 시간이 초과되었습니다.");
                    break;
                  case error.UNKNOWN_ERROR:
                    alert("알 수 없는 오류가 발생하였습니다.");
                    break;
                }
              },
              {
               timeout: 3000 , // 3초 내에 위치 정보 요청
               enableHighAccuracy: true // 높은 정확도 요청
              }
            );
          };
      
          let interval = null;
      
          $('#btnStart').click(function() {
            if(interval){
              clearInterval(interval);
            }
            getPosition();
            interval = setInterval(getPosition, 5000); // 5초에 한번 씩 위치 정보 전달
          }); 
      
          $('#btnStop').click(function() {
            clearInterval(interval);
          });
      
        } else {
          alert("이 브라우저에서는 Geolocation이 지원되지 않습니다.");
        }
      });

    환자의 정보를 지속적으로 갱신해야 하기 때문에, getPosition() 에 interval을 줬고 버튼을 중복해서 클릭하면

    interval이 중복 실행하는 것을 방지하는 코드도 넣었다.

     

    getPosition() 내부의 navigator.geolocation.getCurrentPosition() 함수는 geolocation API의 기능으로

    사용자의 위치 정보를 비동기적으로 가져온다.

    현재 위치 정보를 currentCoords 객체에 저장해서 가져오면, 이것을 HTML에 사용하기 위해

    $('#x').html(currentCoords.latitude);  // 위도 

    $('#y').html(currentCoords.longitude); // 경도

    처럼 원하는 부분에 바로 값을 보내거나, saveLocation()을 이용해서 서버에 위치를 저장했다.

     

    또한 정확한 위치 정보를 얻고 싶고, 실시간으로 위치를 갱신해야하기 때문에

    {
      timeout: 3000 , // 3초 내에 위치 정보 요청
      enableHighAccuracy: true // 높은 정확도 요청
    }
    두 가지 geolocation에서 지원하는 옵션을 추가했다. ( 기본적으로 데스크탑에서는 3km정도의 오차가 발생하고, 모바일의 경우 이보다 적은 오차가 발생하는데, enableHighAccuracy: true를 이용하면 베터리 소모량이 증가하는 대신 거의 정확한 위치 정보를 얻을 수 있다. )

     

    정보를 받아온 다음

    if (navigator.geolocation) 을 이용해서, 정보를 받아올 때 마다 아래의 코드를 이용해 데이터를 DB로 전송할 수 있게 만들었다.

     $.ajax({
              url: '/Geolocation', // 서버의 저장 로직을 처리하는 엔드포인트 URL
              method: 'POST',
              data: {
                name: name,
                phone: phone,
                x: latitude,
                y: longitude
         
              },
              success: function(response) {
                console.log('위치 정보가 성공적으로 저장되었습니다.');
              },
              error: function(xhr, status, error) {
                console.error('위치 정보 저장 중 오류가 발생했습니다:', error);
              }
            });

     

     

    2 - 2. ngrok

    Eclipse의 localhost로 개설한 서버를 다른 pc나 모바일에서 접근할 수 있는 방법이 있다.

    해당 페이지에서 ngrok을 다운로드하고 실행한다.

    EXAMPLES에 있는 명령어를 이용해서 포트넘버를 맞춰야하는데, eclipse의 경우 톰캣으로 실행시키고 있는 서버와 포트번호를 맞춰준다

    -> 위의 톰캣 서버를 열었다면,

    ngrok http <port number>

    다음과 같은 창이 뜨고

    Forwarding 의 주소를 얻을 수 있다. 이 주소는 랜덤하게 배정되며, https: ~ .io 까지의 주소가 localhost:8080으로 접속할 수 있게 만들어준다.

     

    해당 주소로 이동하면

    무료 사용 계정을 생성하고 토큰을 만들어라는 안내문이 나온다.

    토큰은 your authtoken 탭을 클릭하면 자동으로 생성되고

    cmd 에서 ngrok파일이 있는 경로에서 맨 위의 명령어를 실행하면

    다음과 같이 토큰이 등록된다.

    다시 주소를 발급받으면 localhost 서버로 이동할 수 있다.

    이제 다른 기기나 네트워크에서도 내가 실행하고 있는 localhost 서버를 이용할 수 있고,

    내 컴퓨터에 있는 db와도 연동됐다.

     

    하지만 해당 주소를 이용하기 위해서는 내 컴퓨터가 항상 localhost를 실행하고 있어야 하며,

    무료 계정이기 때문에 매일 서버를 갱신해야한다.

     

    3. 결과

    다음과 같이, 이름과 핸드폰 번호를 입력하고 확인을 누르면

    내 컴퓨터에 있는 DB에 이름과 핸드폰 번호, Geo Location Api로 얻은 위도, 경도 값을 저장할 수 있다

Designed by Tistory.