개발 일기

[JUNCTION ASIA 2025] 대학생 마지막 해커톤 | Track 1등 본문

공모전 기록

[JUNCTION ASIA 2025] 대학생 마지막 해커톤 | Track 1등

개발 일기장 주인 2025. 8. 24. 15:39

작년부터 정말 참여하고 싶었던 해커톤이었던 JUNCTION이 8월 22일~24일 포항에서 개최됐다!

작년에 아는 형이 참가하는 모습을 보고 분위기도 멋져 보여서 ‘나도 내년에 꼭 나가야겠다’고 마음먹었던 해커톤이었다. 

그래서 이번 해커톤을 대학 생활의 마지막 대회로 정하고, 꼭 수상하겠다고 다짐했었다.

 

22일에 면접이 있었어서 따로 미리 경상북도에 관련된 이슈에 대해 미리 알아갈 여유는 없었지만 타 해커톤과 다르게 학생, 직장인 할거 없이 참여한다고해서 비록 수상이 목표이긴했지만 즐기고 오자는 생각으로 참여했다.

 

미리 말하자면 전체 1등은 아니었지만, 포항공대·마이크로소프트·경상북도 트랙에서 1등을 차지했고, 트랙 대표로 발표까지 하게 되었다.
직장인 참가자도 있었고, 실력 있는 사람들도 많았으며, 인스타그램에서 보았을 때 카이스트·포항공대 등 내로라하는 고학력자들이 많이 참여했기 때문에 트랙 우승은 전혀 기대안했지만 결국 해냈다!


팀원들과 서울에서 같이 KTX타고 출발했고 조금 일찍 도착해서 게스트하우스에 짐을 풀고 물회 한사발을 했다. 이때, 물회는 고추장 물회였는데 기존에 알던 초장 베이스 물회랑 달라서 신기했고 당연히 맛은 최고였다.

물회를 다 먹고 바로 행사장으로 가서 참가자 등록을 하고 자리를 배분받았다. 근데 성인 4명에서 쓰기에는 너무 좁다는 느낌을 받긴 했지만, 그래도 어쩔 수 없었다. 참고로 대회는 동빈문화창고1969에서 진행했다. 바로 앞에 바다가 있었는데 여유가 없어서 바닷가 근처에도 못갔다.

 

2박 3일 동안 해커톤에 온전히 몰두하기 위해, 대회 시작 직전 잠시 근처의 APT 커피라는 카페에 들러 급한 일을 처리한 뒤 다시 돌아와 본격적으로 대회에 참가했다.

고추장 물회랑 아파트 커피

 

대회 1일차 : 대회 시작 & 기획 단계

대회가 시작되자, 벽면에 빔프로젝터로 4개의 트랙(Track) 이 안내되었고, 각 트랙마다 특정 기업이 제시한 과제가 주어졌다. 참가자들은 해당 기업이 지정한 문제를 해결하는 방식으로 해커톤을 진행하게 되었다.

 

우리는 GYEONGSANGBUCK-DO(경상북도) & POSTECH(포항공대) & MICROSOFT(마이크로소프트) 이렇게 3개의 조직에서 공동 구성한 Track에 참여했다.

해당 슬라이드는 문제되면 바로 내리겠습니다!!

최근 경상북도에서 대형 산불이 발생했는데, 그때 겪은 여러 문제들을 떠올리며 이번 과제가 주어진 것 같다는 느낌을 받았다.

 

특히 나는 대구·경북 지역 출신이라 청송, 안동 등 피해가 컸던 지역에 친척과 지인들이 많이 살고 있었는데, 집이 불에 타 대피소로 피신해야 하는 경우도 많았다. 그래서 자연스럽게 ‘대피와 관련된 주제를 다뤄보면 어떨까?’라는 생각을 했고 관련해서 서칭을 급하게 해보니

 

이러한 이슈들이 있었다.

그래서 단순히 현재 불을 피해 대피 경로를 안내하는 데 그치지 않고, 다음날 불이 번질 가능성이 있는 지역을 예측해 해당 대피소까지 후보에서 제외한 뒤, 안전한 대피소를 추천해주는 서비스를 기획했다.

 

기획만 그날 밤 12시까지 진행했다. 중간에 야식도 주심. 근데 10시쯤에 SnackBar가 열렸는데 1일차라서 그런지 간식을 깔자마자 사람들이 쓰나미 맹키로 다 쓸어가버렸다ㄷ

 

처음에는 단순히 대피소 경로를 추천하는 아이디어에서 출발했지만, 점차 여러 요소가 더해지면서 명확한 페인포인트를 해결할 수 있는 좋은 기획이라는 확신이 들었다. 그리고 무엇보다 중요한 점은, ‘정말 재미있게 개발할 수 있겠다!’라는 생각이 들어 마음에 쏙 드는 주제가 되었다.

 

주제가 정해지자마자 바로 게스트하우스에 쿨쿨따하러감.


대회 2일차 : 본격적인 개발 START

다음날 9시까지 대회장 가려했는데 너무 피곤해서 9시까지 자버렸다. (알람은 듣는 족족 꺼버렸음)

눈뜨자마자 바로 대회장 뛰어가서 빠르게 개발을 시작했다.

 

개발하는 중간 중간에 근처 포항 롯데백화점에 가서 총 30,000원치의 식권을 주셔서 밥을 먹으러 왔다갔다했고 오늘도 APT커피에 가서 커피도 마시고 했다.

APT 커피 & 경인이가 사준 크리스피크림 도나스 & 2일차 야식 포테토 피자

 

개발할때 나의 역할은
우선, 서버 구축(Fast API로 선택)을 해야했다.
1. 산불 예측 모델을 연동하기도 했어야했고,
2. 위도 및 경도로 단순히 직선 거리를 찾는 것이 아니라, OSMnx와 NetworkX라는 라이브러리를 통해 최단 경로를 찾아내야했기 때문이다.

위와 같은 작업을 하기위해서는 파이썬 기반 백엔드 프레임워크가 짱이라고 판단했고,
특히, 단 시간에 개발해야했기 때문에 해커톤에서는 스프링보단 파이썬 기반이 짱인 것 같다.

우리 서비스명

2일차에 빡 집중해서 데모때 보여줄 개발을 완료했고 프론트로 넘겨줬고 하루동안, 개발한 최종 파일 디렉토리이다.

서버 파일 구성은 복잡하지 않게, router에서 엔드포인트만 지정하고 service에 핵심 로직을 분리했으며, 세부적인 메서드들은 utils, dto, models로 나누어 관리하도록 설계했다.

DeFlare-server

개발한 것들에 대해서 적어보자면,

 

익일 산불 발생 예측 모델(multi_kernel_cnn_model)

우선, 모델링 파트는 내가 직접 맡은 부분은 아니었지만, 전반적인 이해가 필요했다. 

여러 논문을 참고하여 모델 구조를 설계했는데, 64km × 64km 지역을 기준으로 각 1km² 셀마다 Elevation, Wind direction, Wind speed, Min temp, Max temp, Humidity 등 총 11가지 feature를 입력값으로 사용한다.

이를 CNN 모델의 Input으로 넣어주면, 최종적으로 64km × 64km 격자의 각 셀에서 익일 산불 발생 여부(0 or 1)를 반환받는다.

 

GPU가 필요했기 때문에 Google Colab에서 모델을 학습시킨 뒤 Export했고, 서버에서는 해당 모듈을 Import하여 추론을 수행하고 예측 결과를 반환받았다. 따라서 사용자가 첫 페이지에 접속할 때, 현재 산불이 발생한 지역과 함께 추론 결과인 익일 산불 예상 셀을 프론트로 미리 전달하도록 구현했다.

 

포항 지리데이터 - GeoJson

위와 같이 구현하기 위해서는 전제가 필요했다.

64km x 64km의 셀들이 포항과 매핑되어 있지 않아, 각 셀을 포항의 특정 지점(위도/경도)과

연결할 수 없었다.

따라서 내가 해당 산불이 날 것으로 예상되는 지역을 포항 위의 특정 지점과 연결하기 위해서는, 미리 포항과 64x64 셀을 매핑해 놓아야 했다.

그래서 나는 서버가 시작되기 전에 포항 GeoJSON 데이터를 추출하고, 포항 시를 셀 위에 올려 고정시켜 특정 위도/경도마다 하나의 셀씩 매핑해 놓았다.

결과적으로 모델 output에 대해 특정 셀을 위도/경도로 변환하여 프론트로 반환할 수 있었고, 프론트에서는 해당 지점을 색칠해 산불이 났음을 표현할 수 있었다.

+ 추가적으로 프론트에서 더 간편하게 처리할 수 있게 하나의 셀에 대해서 좌상, 우상, 좌하, 우하 지점의 위도/경도를 모두 계산해서 넘겨줬다.ㅎㅎ

 

대피소 데이터

이제 모델을 돌린 산불 예측결과를 바탕으로 대피소까지 유저에게 최단 경로를 제공해야했고 우선, 대피소 데이터가 필요했다.

대피소 데이터는 공공 데이터 포털의 경상북도 포항시 대피소 데이터를 활용했고 총 126개의 row가 존재했으며, 데이터 자체에는 String 문자열로 된 주소 데이터 밖에 없었기 때문에 Naver Cloud의 Geocoding이라는 API를 활요하여 주소를 통해 위도/경도를 추출하여 활용했다.

 

대피소까지 안전한 경로로 라우팅해주기

드디어, 가장 중요?한 메인 기능이였다.

고려해야할 사항은 아래와 같다.

 

  1. 최대한 가까운 대피소로 안내해야 한다.
  2. 현재 불이 나고 있는 셀(빨간 셀)은 최종 목적 대피소로 선택해서는 안 되며, 이동 경로에 포함되어서도 안 된다.
  3. 현재 불은 나지 않았더라도 다음 날 불이 날 것으로 예측되는 셀(노란 셀)은 최종 목적 대피소로는 선택되면 안 된다. 다만, 이동 경로에는 포함될 수 있다.

위와 같이 한 이유는?

당장 다시 대피해야 할 가능성은 낮으면서도 가장 가까운 안전한 대피소로 안내하기 위해서였다. 추가로, 노란 셀은 아직 불이 나지 않았기 때문에 경로상에서 지나갈 수는 있도록 했다.

 

자, 이제 위와 같은 고려사항을 바탕으로 경로를 지정해야 했다.

우리는 단순히 목표 대피소만 알려주는 것이 아니라, 그곳까지 이동할 수 있는 실제 경로도 함께 제공해야 했다. 단순히 일직선으로 연결하는 것이 아니라, 실제 도로망(도보 경로)을 따라 안내해야 했다.

 

처음에는 이 부분의 구현이 가능할지 확신이 없었지만, OSMnx와 NetworkX라는 라이브러리를 활용하면 가능하다는 것을 알게 되어 도전하게 되었다.

우선 OSMnx를 이용해 특정 지역의 도로망을 그래프 형식으로 받아왔다. 이후 126개의 대피소를 현재 위치 기준으로 가까운 순서대로 정렬한 뒤, 앞서 정의한 조건들을 하나씩 검사해 최종 목적지로 사용할 수 있는 대피소를 찾았다. 그리고 해당 대피소까지의 최단 경로를 NetworkX로 계산했는데, 이때 내부적으로 우리가 익히 알고 있는 다익스트라 알고리즘(Dijkstra Algorithm) 이 사용된다고 한다.

 

 

 

최종적으로 위와 같이 처리될 수 있도록 했으며, 사실 정말 짧은 시간이였어서 추가적인 고려사항들이 많았지만 그래도 해커톤임에도 불구하고 정말 다양한 것들을 고려했었다.

 

구현을 마친 뒤, 프론트와의 연결을 기다리면서 PPT 구성을 하고 내용을 대략 피그마에 정리해 놓았다. 다음날 디자이너에게 바통을 넘기기 위한 것이였다.

 

할 일을 모두 마치니 새벽 3시가 되었다. 시연 영상을 찍다가 너무 피곤해서 게스트하우스로 돌아갔고, 코피를 쏟다가 그대로 잠들었다. 나이가 드니 이제는 해커톤을 함부로 하면 안 되겠다는 생각이 들었다.


대회 3일차 : PPT 작업 및 발표 + 시상식

3일차 아침에는 늦잠을 자지 않고 대회장으로 향했다. 팀의 디자이너는 피그마로 야무지게 작업을 진행하고 있었고, 우리는 최종적으로 시연 영상을 촬영하며 제출 준비를 했다.

하지만 오후 12시까지 PDF를 구글 드라이브에 업로드하고 링크를 제출해야 했는데, 작업이 늦어져 11시 56분부터 Figma에서 자료를 Export하기 시작했다. 이후 추출한 자료를 구글 드라이브에 올리고 링크를 생성해야 했는데, 하필 처음 Export 과정에서 에러가 나는 바람에 정말 아슬아슬하게 1분도 채 남기지 않고 겨우 제출할 수 있었다.

후에 들은 이야기로는,