코딩공부/COVID-19-REPORT

COVID-19-REPORT . 03 - 지도 API 호출, 위치 저장하기

integerJI 2020. 8. 13. 12:33

COVID-19-REPORT (위치 기록 반응형 웹)

 

결과물

 

메인 페이지

  • 참고 : https://getbootstrap.com/docs/4.5/examples/cover/
  • 현재 사용자의 위치를 저장할 수 있는 페이지
  • 입력하기를 누를 경우 현재 위치의 위도와 경도값을 저장
  • input = text에는 위치의 간략한 설명을 적을 수 있으며 default는 Check

 

index.html

{% extends 'mainBase.html' %}
{% load static %}
{% block maincontent %}
<body class="text-center">
  <div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
    <header class="masthead mb-auto">
      <div class="inner">
        <h3 class="masthead-brand"></h3>
        <nav class="nav nav-masthead justify-content-center">
          <a class="nav-link active" href="{% url 'index' %}">Home</a>
          <a class="nav-link" href="{% url 'list' %}">List</a>
          <a class="nav-link" href="{% url 'signout' %}">Sign out</a>
        </nav>
      </div>
    </header>
    <main role="main" class="inner cover">
      <div id="map" style="width:100%;height:350px;" class="border border-dark"></div>
      <br>

      <form class="form-signin" method="POST" action="{% url 'report'%}">
        {%csrf_token%}
        <input type="text" id="input_report" name="input_report" placeholder="Check">
        <input type="button" id="btn-save" name="btn-save" value="입력하기" />
      </form>

      <br>
      <h1 class="cover-heading"></h1>
      <table class="table">
        <thead>
          <tr>
            <th scope="col">위치</th>
            <th scope="col">위도</th>
            <th scope="col">경도</th>
            <th scope="col">시간</th>
          </tr>
        </thead>
        <tbody id="reportTable">
          {% for report in report.all %}
          <tr>
            <td>{{ report.input_report }}</td>
            <td>{{ report.input_lat }}</td>
            <td>{{ report.input_lon }}</td>
            <td>{{ report.input_time }}</td>
          </tr>
          {% endfor %}
        </tbody>
      </table>

    </main>

    <footer class="mastfoot mt-auto">
      <div class="inner">
        <p class="text-muted font-weight-lighter">&copy; 2020. <a
            href="https://www.instagram.com/integer_ji/">IntegerJi</a> all rights reserved.</p>
      </div>
    </footer>
  </div>
</body>

<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey={{apiKey}}"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript">

  var mapContainer = document.getElementById('map'), // 지도를 표시할 div 
    mapOption = {
      center: new kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표
      level: 2 // 지도의 확대 레벨 
    };

  var map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다

  // HTML5의 geolocation으로 사용할 수 있는지 확인합니다 
  if (navigator.geolocation) {

    // GeoLocation을 이용해서 접속 위치를 얻어옵니다
    navigator.geolocation.getCurrentPosition(function (position) {

      var lat = position.coords.latitude, // 위도
        lon = position.coords.longitude; // 경도

      var locPosition = new kakao.maps.LatLng(lat, lon), // 마커가 표시될 위치를 geolocation으로 얻어온 좌표로 생성합니다
        message = '<div style="padding:5px;">위치를 저장합니다.</div>'; // 인포윈도우에 표시될 내용입니다

      // 마커와 인포윈도우를 표시합니다
      displayMarker(locPosition, message);


      $("#btn-save").click(function () {
        var input_report = document.getElementById("input_report").value;

        $.ajax({
          type: "POST",
          url: "{% url 'report' %}",
          data: { 'csrfmiddlewaretoken': '{{ csrf_token }}', 'input_report': input_report, 'lat': lat, 'lon': lon },
          dataType: "text",
          success: function (data) {
            console.log('성공');
            location.replace("{% url 'index' %}");
          },
          error: function (request, status, error) {
            console.log('실패');
            console.log(request);
            console.log(error);
          }
        }); // ajax END
      }) // btn END

    });

  } else { // HTML5의 GeoLocation을 사용할 수 없을때 마커 표시 위치와 인포윈도우 내용을 설정합니다

    var locPosition = new kakao.maps.LatLng(33.450701, 126.570667),
      message = 'geolocation을 사용할수 없어요..'
    alert('위치를 가져올 수 없습니다. error (01)');

    displayMarker(locPosition, message);
  }

  // 지도에 마커와 인포윈도우를 표시하는 함수입니다
  function displayMarker(locPosition, message) {

    // 마커를 생성합니다
    var marker = new kakao.maps.Marker({
      map: map,
      position: locPosition
    });

    var iwContent = message, // 인포윈도우에 표시할 내용
      iwRemoveable = true;

    // 인포윈도우를 생성합니다
    var infowindow = new kakao.maps.InfoWindow({
      content: iwContent,
      removable: iwRemoveable
    });

    // 인포윈도우를 마커위에 표시합니다 
    infowindow.open(map, marker);

    // 지도 중심좌표를 접속위치로 변경합니다
    map.setCenter(locPosition);
  }    
</script>
{% endblock %}
  • 9 ~ 13 : navbar 영역, 오늘 저장한 위치를 보여주는 index, 지금까지의 모든 위치와 시간을 보여주는 list, 그리고 로그아웃 출력
  • 16 ~ 49 : main 영역으로 지도와 테이블이 들어갑니다.
  • 17 : 지도 출력
  • 60 ~ 143 : javascript 영역
  • 60 : kakao api를 사용하기 위한 apikey 입력
  • 88 ~ 106 : btn-save를 누르는 순간 input값과 위도, 경도를 저장하여 report api를 호출합니다.
  • 참고 : https://integer-ji.tistory.com/215

 

views.py/index

def index(request):
    today = DateFormat(datetime.now()).format('Y-m-d')
    report = Report.objects.filter(input_user=request.user,input_date=today)

    API_KEY = getattr(settings, 'API_KEY', 'API_KEY')

    return render(request, 'index.html', {'report':report, 'apiKey':API_KEY})
  • today 변수에 현재 날짜를 Y-m-d 포멧으로 저장 ex) 2002-02-02
  • report 변수에 현재 접속 유저와 오늘 날짜를 filter하여 데이터를 담아 줍니다.
  • API_KEY는 setting에서 정의해 준 kakao api를 사용하기 위한 key 입니다.
  • 참고 : https://integer-ji.tistory.com/manage/posts

 

views.py/report

@login_required
@require_POST
def report(request):
    if request.method == "POST":
        report = Report()
        report.input_user = request.user
        if request.POST['input_report'] == '':
            report.input_report = 'Check'
        else :
            report.input_report = request.POST['input_report']
        report.input_lat = request.POST['lat']
        report.input_lon = request.POST['lon']
        report.input_date = DateFormat(datetime.now()).format('Y-m-d')
        report.input_time = DateFormat(datetime.now()).format('H:i:s')
        report.save()
        return HttpResponse(content_type='application/json')
  • input_report이 존재하지 않을 경우 'Check'로 저장, 아닐 경우 request 값으로 저장
  • input_date와 input_time를 각각의 날짜, 시간 포멧으로 저장