2 minute read

지도 화면 구성 - 2

한 페이지에 여러 지도 출력하기

  • 어제 그려둔 두번째와 세번째 화면 구성도에 따라 제작하려면, 다음의 문제와 마주하게 된다.
  1. 추천해줄 장소는 여러곳 존재한다.
  2. 리스트 한개당 동적으로 지도 객체를 하나씩 생성해주어야 한다.
  • 결국 디버깅의 세월 끝에 글 작성 시간 기준으로 새벽 세시 반을 넘겨버린 이 문제의 Trouble-Shooting 과정을 기록하기로 했다.

문제1. 리스트는 동적으로 생성.

  • 추천 관광지는 Django에서 JSON 데이터로 보낸다.


  • 추천 관광지의 데이터를 임의로 생성해서 json으로 보냈다. 여기까지는 이상이 없었다…

이스케이프 코드 이슈 - 발단

  • 클라이언트인 html에서 django가 보내준 json 데이터를 파싱하는 과정에서, json 내부의 json을 인식하지 못하는 문제가 발생했다.

  • 어제 result.html의 제작 당시에만 해도

    {{ json이름.key이름 }}

    과 같은 방식으로 해당 key값의 value를 호출할수 있었으나, 이번 추천지 데이터의 recommand_list처럼 value가 또다른 json데이터일때 작은따옴표같은 일부 특수기호들이 이스케이프 코드로 변환되어 들어오는것을 확인했다.

    • 이런 변환이 일어나는 XSS 공격에 대응하기 위해서라고 한다.

이스케이프 코드 이슈 - 해결

  • 해결에 도움을 받은 정리글에서는 두가지 해결법을 제안한다.

    • replace를 통해 문제가 되는 특수문자를 제거
    • django의 templates filter인 json_script 활용
  • 그중 json_script를 활용하는 방법을 사용하기로 했는데, 다음과 같은 이유가 있었다.
    • replace를 사용하기에는 json이 이중으로 작성되어있어 상당히 번거로운 작업이 예상됨.
    • 추천 데이터 리스트의 개수가 많아질수록 반복문을 돌려 replace하는 방식은 비효율적일것으로 예상됨.
  • json_script 필터를 돌려 파이썬 객체를 JSON객체로 출력해준다.

  • 그 후, 변환되어 JSON객체가 된 데이터를 파싱해주면 데이터 추출 완료.

리스트 항목의 동적 생성 이슈 - 발단

  • 추출한 json객체의 데이터를 기반으로 반복문을 돌려 하나씩 리스트를 생성하려던 도중
  • 리스트에 사용하던 bootstrap의 클래스와 충돌이라도 하는건지 JQuery의 $(‘클래스이름’).html(추가할 내용)의 방식을 사용할수 없는 문제가 발생함.

리스트 항목의 동적 생성 이슈 - 해결

  • 결국 해당 이슈의 원인은 찾지 못했다.
  • 임시방편으로 <script>태그를 <ul>태그 안쪽에 넣어 반복문을 실행하였다.
  • 반복문 내부에는 document.write()문을 사용하여 html태그를 텍스트로 직접 생성하는 방식을 택했다.
  • 이 과정에서, 지도를 나타나고 숨기는 자바스크립트가 포함된 버튼까지 수동으로 써넣어야 했기에, 코드가 엄청나게 지저분해졌다.

  • 결과물은 다음과 같다.

문제2. 지도의 다중 생성

  • 리스트의 내용(장소) 하나 당 해당 위치를 보여주는 지도 하나가 생성되는것이 기능적으로 옳다고 판단했었다.
    • 하나의 지도로만 표시하여 리스트 내의 버튼을 클릭하면 해당 위치를 보여주는 방법도 있긴 하다.
    • 하지만 사용자의 입장에서 여러 장소의 위치를 비교해야 하는 상황일때 그러한 방식은 불편을 줄 가능성이 있었기에, 리스트 하나당 하나의 지도를 생성했다.
  • 여태까지 통상적으로 써온 방법(result_page)으로는 한 페이지에 하나의 map 객체만 생성할수 있었다.
    • 따라서, 동적으로 map을 아무리 생성한들 가장 처음 만들어진 map 객체의 지도만 작동했다.

지도 다중 생성 이슈 - 해결

  • 이를 해결하기 위해 조사하던 도중, 해결 방법을 찾을수 있었고, 바로 적용했다.

  • 커스텀 클래스의 파라미터로 지도 구성 요건을 채우고 해당 클래스의 id를 기반으로 map과 marker를 연결하는것이 핵심이다.

  • 내가 적용한 코드는 다음과 같다.

  • 참고한 예제와 달리 마커 클릭시 나오는 infoWindow를 생성해 달아주었고, 받은 인수들을 mapOptions로 정리해주었다.

그 외 각종 버그들 및 해결

  • 활성화된 지도의 크기 비정상적 출력
    • 지도 객체 클래스의 display를 none으로 설정했다가 inline-block으로 변경시 발생.
    • 구글 지도 api docs의 설명에 따르면, display:none 설정시 지도 사이즈를 0*0으로 인식한다고 함.
    • 이런 상황에서 inline-block등으로 style을 재설정시 기존에 설정해둔 style의 크기를 벗어나는 현상이 관찰됨.
    • 지도 객체는 display:hidden으로 설정하고 지도를 감싸는 div영역을 설정하여 해당 div의 display를 none으로 만들면 해결된다.
    • 해당 코드는 다음과 같다.

  • 그렇게 구현한 결과물은 다음과 같다.

  • 기능적으로 옳아보이는 것이 때론 구현하기 힘든 방법일수 있다는것을 알았다.

내일 해야 할 일

  • Front-end
    • 지오코딩으로 좌표 -> 주소 변환 기능 추가.
  • SQLD 공부