엎코닿

cdc wiki
이동: 둘러보기, 검색

목차

프로젝트 개요

기술개발 과제

국문 : 생활 활동 반경을 고려한 주거 지역 추천 애플리케이션

영문 : Applications for Recommending Residence Considering The Radius of Living Activities

과제 팀명

엎코닿(UpKoDah, 엎어지면 코 닿을)

지도교수

황혜수 교수님

개발기간

2020년 9월 ~ 2020년 12월 (총 4개월)

구성원 소개

서울시립대학교 컴퓨터과학부 2015XXX0** 정*훈(팀장)

서울시립대학교 컴퓨터과학부 2014XXX0** 정*준

서울시립대학교 컴퓨터과학부 2014XXX0** 최*환

서울시립대학교 신소재공학과 2015XXX0** 김*현

서론

개발 과제의 개요

개발 과제 요약

본 애플리케이션은 통근·통학을 위한 주거지 선정 시, 사용자의 삶의 질 향상을 기대한다.
사용자가 목표지점을 선택하면 버스 · 지하철을 이용한 통근 · 통학 시간 및 수단, 주거지 주변의 근린생활시설 유무를 분석하여 사용자에게 적합한 주거지를 추천한다.


개발 과제의 배경

  • 2015년 인구주택 총조사에 따르면, 12세 이상 인구의 통근율은 53.4%에 달하며, 통근·통학 인구 중 거주지 시군구 외로 통근·통학하는 인구의 비율은 34.2%에 달한다. 매일 많은 인구가 집과 직장, 혹은 집과 학교를 오고 가게 되면서 많은 시간을 길에서 소비하게 되고, 또 지역에 따라서는 심한 교통체증으로 인해 고통을 당하기도 한다. 따라서 통근과 통학 양상은 이들의 삶의 질에 직접적으로 영향을 미치게 된다.
  • 기존 기술과의 비교 : ‘직방’
  1. 전·월세, 보증금, 구조, 층수 등의 옵션
  2. 편의시설 관련 정보 없음
  3. 주거지 주변 교통 정보 제공
  • 기존 기술과의 비교 : ‘다방’
  1. 전·월세, 보증금, 기타 옵션
  2. 주변의 편의시설 정보 제공
  3. 주변 교통 관련 정보 없음
  • 기존 기술과의 비교 : ‘네이버 부동산’
  1. 편의시설 정보를 지도상에 표시하여 매물을 동시에 표시
  2. 특정 지역을 선택하면 예상 도착 시간대별 부동산 매물 표시
  • 기존 부동산 정보 애플리케이션은 지도상에서 특정 지역의 거래가, 옵션 등에 따라 필터링한 주거지의 목록을 제시하고, 한 주거지의 상세정보를 선택할 때 편의시설 등의 정보를 제공한다.
  • 기존 부동산 정보 애플리케이션은 목표지점에 도달하는 데 드는 시간에 따라서 이웃한 지역구의 부동산 정보를 보여주는 데 그친다. 또 이동 시 발생하는 시간 비용이 아닌 육체적, 경제적 비용은 고려하지 않는 경향이 있다. 본 애플리케이션은 통근·통학 시 대중교통의 환승 횟수와 시간을 고려한 주거지를 제안함으로써 사용자 편의를 제공하고자 한다.


개발 과제의 목표 및 내용

  • 이번 과제의 목표는 주거 예정인 지역이 아니라, 사용자가 직장이나 학교 등 활동 반경을 검색하면, 편의시설 등 근린환경을 고려하여 적절한 주거 지역을 찾아주는 애플리케이션을 개발하는 것이다.
  • 시나리오 (직장인 예시)
1. 주거 제안 앱은 네트워크 환경을 체크 후 지도가 나와 있는 기본 페이지를 보여준다.
2. 사용자는 지도에서 직장 위치를 등록하고, 원하는 이동 시간을 입력한다.
3. 주거 제안 API에 위치와 시간을 담아 request한다.
4. 주거 제안 API 서버는 공공 데이터에서 해당 위치로부터 원하는 이동 시간 안에 도달할 수 있는 지역을 찾아 후보 지역 리스트로 만든다.
5. 주거 제안 API 서버는 후보 지역 리스트에서 각 지역의 주변 편의시설 등의 요소들을 고려하여 주거하기에 적합한지 판별 후 적합할 시 주거 지역 리스트에 넣는다.
6. 주거 제안 API 서버는 주거 지역 리스트를 JSON 포맷으로 response한다.
7. 주거 제안 앱은 사용자에게 주거 지역 리스트를 보여준다.
  • 지도 API 기술은 편의시설 검색 기능과 지도 출력 기능이 원활한지에 따라 카카오 로컬 API를 채택한다.
  • 교통 정보 API는 버스 노선과 지하철 노선 공공 API를 활용한다. (공공데이터포털)
  • 부동산 매매 정보는 관련 API를 활용하거나 Web Crawling 기술을 활용하여 구현한다.
  • 애플리케이션 동작 환경은 Android 운영체제로 하며, 애플리케이션 개발에는 Android Studio를 활용한다.
  • 서버 구성은 Gcloud의 서버(GCP)를 메인 서버로 하여 Kubernetes 환경을 구축하고, 추가적인 기능을 하는 서버들을 도커 컨테이너로 디플로이하여 관리한다. 추가 서버에는 매물 데이터를 크롤링하기 위한 Python 기반 크롤링 서버, MySQL 기반 DB 서버, 길찾기 및 추천 알고리즘을 구동하는 서버 등이 있다.

관련 기술의 현황

State of Art

클라우드 서비스

구글이나 카카오, 네이버 등의 대형 포털을 운영하는 사이트들은 방대한 양의 데이터를 모으고, 이를 API의 형태로 제공하고 있다. 제공되는 기술은 이번 과제에서 사용할 지도 관련 기술뿐만 아니라 번역, 음성인식, OCR 기술, 메신저, 검색, 가상 서버 등 다양하다. 이들은 이러한 기술을 제한된 범위 내에서 무료로 제공하고 있으며, 각 개발사 사이트에 들어가 지정된 등록 절차를 거쳐 활용할 수 있다.

  1. NAVER 클라우드 OpenAPI
  2. 카카오 개발자 OpenAPI
  3. 구글 클라우드 플랫폼
정보 공공 데이터 포털

공공 데이터 포털은 공공기관이 생성 또는 취득하여 관리하고 있는 공공데이터를 한 곳에서 제공하는 통합 창구다.(출처 : 공공데이터포털 소개) 공공 데이터 포털의 각 공공 데이터를 받는 방법은 이용 신청 후, REST API를 이용해 HTTP GET 메소드를 활용하여 JSON 형태로 반환 받은 데이터를 활용할 수 있다.

 제21조(공공데이터포털의 운영) [관련 법령 : 공공테이터의 제공 및 이용 활성화에 관한 법률]
 ① 행정안전부장관은 공공데이터의 효율적 제공을 위하여 통합제공시스템(이하 "공공데이터포털"이라 한다)을 구축·관리하고 활용을 촉진하여야 한다.
 ② 행정안전부장관은 공공기관의 장에게 공공데이터포털의 구축과 운영에 필요한 공공데이터의 연계, 제공 등의 협력을 요청할 수 있다.
   이 경우 요청을 받은 공공기관의 장은 특별한 사유가 없는 한 이에 따라야 한다.
 ③ 그 밖에 공공데이터포털의 구축·관리 및 활용촉진 등 필요한 사항은 대통령령으로 정한다.
서버 상용 기술

서버 개발은 크게 서버 하드웨어 구축, 서버 운영체제 설치, 서버 프로그램 운영이라는 세 가지 방식으로 나누어진다. 이전에는 간단한 서버용 장비를 구매하여 구축하는 일이 많았으나, 과거에 비해 네트워크 속도가 비약적으로 상승하여 일부 기업에서는 서버 자원을 이용할 수 있는 환경을 제공한다. 이러한 클라우드 서버를 통해 서버 하드웨어 설계와 운영체제 설치 부담을 줄여 비용을 절약할 수 있다.

  1. 아마존 AWS(Amazon Web Services)
  2. 구글 클라우드 플랫폼(GCP)

서버 프로그램 개발을 위한 프레임워크도 많이 등장했다. 조금 더 개발자 편의를 제공하는 파이썬(Python) 등의 프로그래밍 언어가 등장하면서, 편리한 언어를 지원하는 서버 개발 프레임워크가 등장하였다. 그 중, Python이나 Go언어 기반으로 동작하는 프레임워크도 있고, 한국전자정부프레임워크로 Java 기반의 Spring이 있다.

  1. Flask 프레임워크 : Python 기반, 유연한 기능 확장
  2. DJango 프레임워크 : Python 기반, 편리한 사용성, 빠른 개발
  3. Spring 프레임워크 : Java 기반, 한국 전자정부프레임워크 표준
  4. Node.js : JavaScript 기반
  5. Gin : Go언어 기반의 서버 프레임워크
모바일 애플리케이션 개발 기술

모바일 애플리케이션의 대표적인 OS는 Android와 iOS가 있다. 둘은 구동 방식에 차이가 있어 하나의 애플리케이션으로 만들기 어렵다.

  1. Android : Java 및 Kotlin 기반, Android OS 전용, Android Studio 활용
  2. iOS : Swift 기반, MacOS, iOS등 Apple사 OS 전용, XCode 활용

만약 위 두 도구 중 하나로 애플리케이션을 개발한다면, 기본적으로 한 가지의 OS에서만 모바일 애플리케이션 구동이 가능해져 각 플랫폼의 애플리케이션을 모두 개발하여야 한다는 문제가 존재한다. 이러한 문제를 해결하기 위해, 크로스플랫폼 모바일 애플리케이션 개발을 지원하는 프레임워크가 존재한다.

  1. React Native (https://reactnative.dev/) : JavaScript 기반의 Android, iOS 크로스플랫폼 개발 프레임워크. 방대한 양의 커뮤니티 및 인프라가 구축되어 있다.
  2. Flutter (https://flutter.dev/) : Dart 기반의 Android, Window, iOS, LINUX 크로스플랫폼 개발 프레임워크. Android studio로 개발할 수 있다.


기술 로드맵

지도 API의 선택

먼저, 지도를 출력하는 API는 카카오 지도 API나, 네이버 지도 API, 구글 클라우드 지도 API 등 다양한 공공 API를 활용할 수 있다. 여기에서 얻어지는 좌표(위도 및 경도)는 네이버의 Geocoding이나 카카오 로컬 API 등을 이용해 자유로운 변환이 가능하다. 조사된 것은 다음과 같다.

API 기능
카카오 지도 API 지정 위치의 지도를 표시하고 줌 인 및 줌 아웃 기능을 지원하며, 지도 위에 마커를 이용해 상세 위치를 표시할 수도 있다.

또한, 지정된 교통 수단을 이용한 간단한 길찾기 기능도 가능하다.

네이버 지도 API
네이버 Geocoding 주소를 좌표계로 변환하거나, 좌표계를 주소로 변환한다.
카카오 로컬 주소를 좌표계로 변환하거나, 좌표계를 주소로 변환한다. 또한, 특정 키워드를 검색하여 키워드와 관련된 매물을 얻어내는 기능 역시 제공된다.
버스 및 지하철 API의 획득

이번 과제는 지정 위치로부터 대중교통이나 도보로 제한시간 이내에 갈 수 있는 매물을 찾아내는 것이다. 도보라면 특정 위치를 기준으로 소요 거리를 지도 API의 길찾기 기능을 통해 계산할 수 있다. 하지만, 버스나 지하철의 경우에는 API로 해결할 수가 없다. 이번 과제의 핵심은 ‘버스나 지하철로 환승 없이 직통으로 갈 수 있는 매물’이다. 일반적인 대중교통 길찾기는 자가용을 이용한 길찾기나, 단순 대중교통에 대한 질의만 가능하지, 환승 여부 등을 선택한 대중교통 검색은 불가능했다.

UpKoDah 카카오맵으로대중교통검색불가.png


하지만, 특정 위치를 선택했을 때, 가까운 버스나 지하철 정류장의 위치를 얻어내는 것은 가능하다. 그렇다면, 버스나 지하철 노선 정보만 알아낼 수 있다면, 특정 정류장에서 다른 정류장까지 도달하는 시간을 계산할 수 있으므로, 과제 수행에 문제가 없어진다. 노선 정보에서 필요한 것은 노선 간 소요 시간이다. 문제는 지하철의 경우, 노선 간 소요 시간을 비교적 쉽게 얻어낼 수 있는 반면, 버스는 관련 API도 없고, 전국에 노선 수가 40만 개가 넘어 간접적으로 조사하더라도 저장할 수는 없을 것으로 보인다.

부동산 매물 획득 방법

부동산 매물의 처리 방식은 직거래하거나 중개업소를 통해 매매/대여하는 방식이다. 직거래의 경우 매매계약서를 작성하는 등 불편이 있어 중개업을 통해 거래하게 되며, 이때 중개료 또는 복비를 중개업자에게 지급하게 된다. 2012년 초에, 네이버 부동산이 중개업을 대행할 수 있는 기능을 가지고 있었는데, 2013년에는 반발로 인해 매매 사업을 중단한 것으로 알려져 있다. 이에 네이버 부동산은 중개업이 아닌 ‘정보 지원 플랫폼’으로 운영되고 있다. 이 플랫폼은 중개업자들이 매물을 올리면서 중개업을 홍보하고, 그 광고료(홍보 비용)를 지불하는 방식으로 운영되고 있다.

결론은, 현재 부동산 사업은 ‘정보 지원 플랫폼/서비스’와 ‘부동산 중개업’의 구조로 나뉘어 있다. 지원 서비스는 중개업소를 소개하는 방식으로 운영되고, 수익은 중개업자들이 내는 광고료로 얻는다. 이렇게 된다면, 직방이나 다방, 네이버 부동산의 주 수익이 중개업자들의 광고료가 되며, 주 수익원인 매물 정보를 공유할 이유가 없어 진다. 그렇기 때문에 실제 제공되는 API는 찾아볼 수 없었으며, 부산시대 부동산 등의 사이트가 있으나, 대부분 폐쇄되거나, 한정적인 범위의 매물만 올라와 활용 가치가 떨어졌다.

따라서, 부동산 매물 정보를 얻기 위해서는 크롤링이나 중개업소의 자료를 받는 것이 강요될 것으로 보인다. 하지만, 크롤링 역시 활용할 수가 없다. 다음은 네이버 이용약관 중 일부다.

 네이버의 사전 허락 없이 자동화된 수단(예: 매크로 프로그램, 로봇(봇), 스파이더, 스크래퍼   등)을 이용하여 네이버 서비스 회원으로 가입을 시도 또는 가입하거나, 네이버 서비스에 로그인을 시도 또는 로그인하거나, 네이버 서비스 상에 게시물을 게재하거나, 네이버 서비스를 통해 커뮤니케이션하거나(예: 전자메일, 쪽지 등), 네이버   서비스에 게재된 회원의 아이디(ID), 게시물 등을 수집하거나, 네이버   검색 서비스에서 특정 질의어로 검색하거나 혹은 그 검색결과에서 특정 검색결과를 선택(이른바 ‘클릭’)하는 등 이용자(사람)의   실제 이용을 전제로 하는 네이버 서비스의 제공 취지에 부합하지 않는 방식으로 네이버 서비스를 이용하거나 이와 같은 네이버 서비스에 대한 어뷰징(남용) 행위를 막기 위한 네이버의 기술적 조치를 무력화하려는 일체의   행위(예: IP를 지속적으로 바꿔가며 접속하는 행위

위 약관을 고려하면, 네이버 서비스는 이용자의 실제 이용을 전제로 하므로, 로봇(크롤링)을 기본적으로 거부하고 있음을 알 수 있다. 따라서, 크롤링을 이용해 제품을 만드는 것은 일단은 불가능할 것으로 보인다.

애플리케이션 개발 프레임워크 선택

개발 프레임워크 선택에서 중요한 사안 중 하나는 ‘친밀성’이다. 물론 다른 고려 사항도 있으나, 애플리케이션 개발은 사용자 입장의 프론트엔드 수준의 개발이기 때문에 선택 범위 내 프레임워크가 기능 및 기술지원이 사용하기에 문제가 없다면, 성능적인 부분보다는, 짧은 개발 기간을 고려하여 친밀성이 높은 안드로이드 스튜디오를 활용해 Android OS 지원용 애플리케이션을 개발한다. 크로스플랫폼 환경은 고려하지 않도록 한다.

하지만, 만약 이후 크로스플랫폼을 고려할 경우, Android Studio를 동일하게 활용하여 Flutter를 두 번째 선택안으로 활용할 수 있을 것으로 보인다.


서버 하드웨어 구성 및 프레임워크 선택

서버의 인프라를 처음부터 구축하는 것은 프로젝트 기간과 비용을 고려했을 시 거의 불가능에 가깝다. 이에 따른 대안으로 서버 호스팅이 있다. 원래는 기존에 물리 서버에 대해 고려하여 다음과 같이 물리 서버 비용을 산정했다.

CPU Core Thread Clock Cache RAM Graphic
Intel Celeron CPU G1820

(소지)

2 2 2.70GHz 2MB DDR3

최대 8GB

O
AMD Athlon II x2 245

(소지)

2 2 2.90GHz 2MB X
Intel Xeon X5670

(최대 2개)

(미소지, 예산으로 구매)

6(12) 12(24) 2.93GHz 12MB DDR3

24~48GB

X



먼저, NAS나 단순 연산 서버의 경우는 위쪽 2개로도 충분히 구현 가능하나, 이번 과제는 수시로 외부 API 호출 및 성능 개선을 위한 DB 사용도 고려하고 있어 성능상으로 부족하다고 판단했다. 과제를 위한 수준으로 일반 PC나 서버용 메인보드를 구매하는 것을 고려한 것이 3안이지만, 신 제품은 예산 범위를 초과하며, 중고 제품은 구매 후 고장 발견 시, 대처가 곤란해진다는 문제가 있다. 대안인 서버 호스팅에 비해 별다른 이점이 없을 것으로 판단하여 서버 호스팅으로 결정했다.

서버 호스팅 업체의 경우 가장 대표적으로 쓰이는 GCP(Google Cloud Platform)과 AWS(Amazon Web Services) 두 업체가 있다. Kubernetes 클라우드 환경에서 Mysql와 Server API를 띄우도록 했을 시 GCP 경험이 있는 팀원이 있어 개발 기간을 단축할 수 있기 때문에 GCP 인프라를 토대로 개발한다. 서버 프레임워크 후보로는 Java의 Spring, Golang의 Gin, Javascript의 Nodejs가 있다. 서버의 주된 기능은 시간에 따른 부동산 매물을 반환하는 것이고, 사용자의 응답을 고려할 때 Golang의 동시성 지원이 큰 이점으로 작용할 것으로 보이기에 Golang의 Gin framework를 사용하여 서버를 개발한다.

시장 상황 분석

경쟁제품 조사 비교

UpKoDah comparison apps01.png

UpKoDah comparison user.png

UpKoDah comparison.png

마케팅 전략 제시

마케팅 전략은 SWOT 분석 기법을 이용해 강점(S, Strength), 약점(W, Weakness), 기회(O, Opportunities), 위협(T, Thread) 네 가지로 분석한다.

  • S (Strength) - 내부 분석 중 강점
  • W (Weakness) - 내부 분석 중 단점
  • O (Opportunities) - 외부 분석, 기회
  • T (Threat) - 외부 분석, 위협



  • 사용자 편의성 : 부가 기능에 접근하기 좋음
  • 매물을 조사하면서 편의성까지 검색할 수고가 줄어 듦.
  • 학부생 수준의 연구 개발의 한계
  • 제휴업체(부동산 매물) 확보 : 중소기업의 약한 경쟁력
  • 브랜드의 인지도 – 생소한 브랜드에 대한 신뢰성
  • 대중교통에 한정된 분석 결과
S
W
O
T
  • 편의를 원하는 요구자
  • 대중교통 및 편의시설 요구
  • 자가용을 이용한 통근자
  • 네트워크 외부성 : 익숙한 브랜드를 선호하는 경향
  • 요구 빈도 : 주거 이전을 요구하는 빈도가 낮음
  • 대중교통 편의는 도시에 집중

개발과제의 기대효과

기술적 기대효과

  • 사용자가 살기 적합한 지역을 선택하기 위한 고민이 줄어든다. 기존 애플리케이션은 자신이 살고자 하는 지역을 직접 통근 및 통학 위치를 고려하고, 가격 등을 생각하며 선택해야 했지만, 이번 과제는 통근 및 통학 위치만 선택하면, 접근성이 좋은 매물이 있는 지역을 골라주게 된다. 이러한 장점은 사용자에게 좀 더 편리한 검색 환경을 제공하게 될 것이다.


경제적, 사회적 기대 및 파급효과

  • 애플리케이션이 활성화된다면, 특정 지역 위주의 매물 및 가격 형성이 아닌, 수요자에 의한 가격 형성으로 어느 정도 변화를 줄 수 있을 것이다. 이는 문재인 정부의 부동산 정책의 ‘실수요자 위주’ 정책에도 부합할 것이며, 실수요와 무관한 투기과열지구 문제도 어느 정도 해결해줄 수 있을 것으로 기대할 수 있다. 물론, 부동산 시세 자체가 이미 접근성이 가격에 포함되었다고 생각할 수 있어 어느 정도의 효과가 있을지는 미지수다.
  • 현재 대중교통 중, 특히 버스 노선은 별도의 수요 조사를 통해 진행되고 있다. 하지만, 이러한 방법은 수요 조사 참여자에 국한되기 때문에 분명 한계가 존재한다. 이번 과제에서 개발될 애플리케이션은 통근 위치를 지정하면, 대중교통 접근성에 따라 매물을 결정하게 되며, 여기에서 얻어지는 출발지-목적지 데이터를 수집할 수 있다면, 버스 노선에 대한 수요 조사가 가능하다. 이러한 점은 정부의 스마트시티 사업에도 부합한다고 볼 수 있다.



기술개발 일정 및 추진체계

개발 일정

UpKoDah schedule.png



구성원 및 추진체계

UpKoDah progress.png




업무 목록
  • 사용자 애플리케이션
  • 데이터 분석: API 및 Web Crawling을 기반으로 수집한 데이터를 분석
    1. 교통 정보
    2. 근린생활시설/편의시설
  • 데이터 가공: Web Crawling을 통한 데이터베이스 마련
  • 서버 구축
  • 데모 애플리케이션: 분석한 데이터를 애플리케이션 내에 시각화


업무 분담
  • 정성훈(팀장): 데이터 분석
  • 정상준: 데이터 분석, 크롤러 구현
  • 최중환: 클라이언트(안드로이드) 개발
  • 김유현: 크롤러 구현, 서버 환경 개발

설계

설계사양

제품의 요구사항

사용자 요구사항을 조사하고, 이를 만족시키는 데 필요한 시스템 요구사항을 분석한다.

R1: 통근할 목적지에 따라 원하는 매물을 찾을 수 있으며, 목적지를 지도에서 선택할 수 있음
R2: 현재 자기 자신의 위치를 목적지로 선택할 수 있으며, 지도에서 확인할 수 있음
R3: 검색된 매물이 지하철이나 버스 등 대중교통으로 편하게 접근 가능한 위치임
R4: 도착하는 데 걸리는 시간을 설정할 수 있음
R5: 매물 주변에 있어야 하는 편의시설을 선택할 수 있음
R6: 거래 타입(월세, 전세), 그리고 방의 형태(원룸, 오피스텔 등)를 선택할 수 있음
R7: 매물을 검색하면 지도에서 구 단위, 동 단위로 매물을 묶어서 보여줌
R8: 검색 결과 매물 목록 UI를 지원
R9: 검색 결과 매물을 여러 장의 사진과 함께 보여줌
R10: 검색 결과 매물의 상세 위치 및 주변 시설을 지도를 통해 확인할 수 있음
R11: 거래자의 연락처로 연결하여줄 수 있음
R12: 검색 결과가 5초 이내로는 나와야 함
R13: 안정적인 서비스를 위해 서버가 다운되거나 업데이트로 인해 정지하는 일이 없어야 함

설계 사양

F1: 검색 조건으로 목적지, 제한시간, 매물 유형, 방의 형태, 편의시설 필터를 입력 (입력 인터페이스)
F2: 지도에는 특정 위치를 표시할 수 있음
F3: 지도에는 특정 아이콘과 지역을 나타낼 수 있는 글자를 써서 위치와 함께 표현할 수 있음
F4: 지도의 확대 수준에 따라 구, 동, 지역 단위로 매물을 묶어서 보여줄 수 있음 (클러스터링)
F5: 지도 API를 통한 지도 UI의 구현 및 매물 정보 등의 전시
F6: 연락을 위한 휴대 단말의 전화, 문자 등 연락처로의 리디렉션 기능
F7: 사용자 자기 자신의 위치를 가져오고, 표시할 수 있음
F8: 원하는 매물은 대중교통 편의를 고려할 수 있도록 정류장 또는 역 기준으로 검색
F9: 검색될 매물은 속도를 위해 검색에 용이한 형태로 서버에 미리 저장 (캐싱)
F10: 검색 성능을 높이기 위한 third-party API에 대한 비동기 처리 기능
F11: 서버가 다운되는 일이 없도록 3개 이상의 pod를 띄우고, 로드 밸런싱을 함
F12: 서버가 업데이트를 하더라도 중단되지 않도록 멀티 서버와 무중단 배포를 구현

개념설계안

부동산 매물 API 개념 설계안

[지원되어야 할 기술]
: 거래 중인 매물의 위치(좌표), 매물의 거래 정보(전세, 월세, 가격), 매물의 형태(원룸, 아파트, 단독주택) 등


대중교통 노선 정보 API 개념 설계안

[지원되어야 할 기술]
: 버스 및 지하철의 노선 정보, 정류장 위치(좌표), 노선 간 소요 시간, 환승 경로 조회

먼저, 대중교통에서 가장 문제가 되는 부분은 버스의 노선 정보다. 버스의 노선 개수는 전국 40만 개가 넘기 때문에, 서버 내에서 저장하여 처리하기엔 무리가 있어 외부 API가 강제된다.

  • Idea 1
    네이버나 카카오 지도 API의 대중교통 경로 검색을 활용한다.

UpKoDah concept trans01.jpg

  • Idea 2
    공공데이터포털 활용하여 노선 정보를 얻어오고 시간 직접 계산

UpKoDah concept trans02.jpg

  • Idea 3
    ODSay 유료 API 활용

UpKoDah concept trans03.jpg

지도 및 위치정보 API 개념 설계안

[지원되어야 할 기술]
: 지도 기능 제공, 키워드 검색을 통한 범위 내 시설 검색, 좌표의 주소 변환 및 주소의 좌표 변환


UpKoDah concept map.jpg



지도 API가 지원해야 할 기술은 크게 세 가지다.

지도 기능 사용자 애플리케이션 내에서 사용자의 목적지 선택, 그리고 매물 검색 결과 출력을 위해 사용된다.
키워드 검색 기능 사용자의 목적지에서 가까운 정류장의 위치를 반환한다.
검색된 매물 주변에서 가까운 편의시설 등의 위치를 반환한다.
좌표 주소 변환 사용자의 위치 정보 및 각종 API의 검색 결과가 주소가 아닌 좌표(위도, 경도)로 반환될 때, 주소 변환을 위해 사용한다.

매물 질의 개념 설계안

이번 과제의 핵심 기능인 매물 질의에 대한 개념 설계안이다. 사용자의 입력에 대해 무엇을 기준으로 매물을 검색할 것인지를 아이디어를 제시했다.

  • Idea 1
    사용자의 위치에서 도달 가능한 정류장까지를 사각형 범위로 포함시켜 해당 매물을 가져온 후, 각 매물에 대해 정류장 접근성을 검사하고 정리해서 매물을 보여 준다.
    UpKoDah concept search Idea1.png
  • Idea 2
    사용자의 위치에서 시간 내에 도달 가능한 정류장에서 일정 거리 범위 질의를 수행한다. 정류장에서 도달 가능한 매물은 성인의 평균 보행속도 4~4.5km/h로 5분 안에 접근할 수 있는 400m 이내로 한다.
    UpKoDah concept search Idea2.png
  • Idea 3
    사용자의 위치에서 환승 없이 하나의 교통 수단을 이용해 도달 가능한 정류장에서 일정 거리 범위 질의를 수행한다.
    UpKoDah concept search Idea3.png

이론적 계산 및 시뮬레이션

그리드 분할 크기 계산

대부분의 부동산 및 지리정보 애플리케이션은 뷰의 가독성과 응답성을 높이기 위해서 클러스터링을 이용하여 엔티티를 표현한다. 기본적으로 행정구역을 기준으로 분할하고 더 낮은 수준의 클러스터를 제공할 수 있다. 본 앱에서는 특정 좌표(서울시립대)를 기준으로 대한민국 전역을 일정 크기로 나누어 그리드 맵을 구성한다. 성인이 약 5분 걷는 거리인 400m단위 그리드 크기로 설정. 그리드는 기준좌표에서 시작하여 대한민국 최극단까지를 단위 크기로 나눈다. 여기서 단위 그리드 크기 400m는 좌표 변량으로 변환되어야 한다. 이 변환에 Geodesic 알고리즘 중 타원 구면체(Ellipsoid)에 대한 거리-지리좌표 변환 정리인 Vincenty’s Formulae를 사용했다.

* Vincenty’s Direct: 지리좌표, 거리, 방위각을 대입하여 다른 지점의 좌표와 방위각을 구하는 정리
* Vincenty’s Inverse: 두 지점의 좌표를 대입하여 방위각과 거리를 구하는 정리

서울시립대 좌표 37.5838657N, 127.0565884E를 기준좌표로 삼고, 400m의 거리에 대해 방위각(azimuth) 0도와 90도로 Vincenty’s Direct 계산을 한다.

azimuth = 90°일 때, 37.5838657° N, 127.0565884° E인 점에서 400m 떨어진 지점의 지리 좌표는, 37.5838656° N, 127.0611171° E이다. 위도상에서는 0.1×10-7° 정도의 차이를 보이고 경도상으로는 0.0045287의 차이가 존재한다.
azimuth = 0°일 때, 동일한 좌표에 대해서 400m 떨어진 위치의 좌표는 37.5874697° N, 127.0565884° E가 된다.
그리고 경도가 동일하며, 위도는 0.003604°의 차이를 보인다. 본 앱에서는 계산의 편의를 위해서 0.0036을 그리드의 단위값으로 설정하였다. 지구를 타원 구면체로 가정한 까닭에 위도에 대해서는 거의 일정한 값을 같지만, 위도가 달라질 때 경도에서의 좌표 차이는 꽤 달라질 수 있다. 경위도 두 방향으로 0.0036으로 설정하여, 위도로는 400m, 경도로는 320m(317.975)차이를 보인다. Google Earth에서도 본 앱의 기준에 가까운 위도 약 400m, 경도 약 320m 의 최소 그리드를 사용한다.

Google Earth 최소 그리드 크기
UpKoDah google grid latitude.png UpKoDah google grid longitude.png
위도 경도



그리드가 적용되는 범위에서 경도의 차이를 살펴보자면, 본 앱에서 거리가 적용되는 범위인 서울 지역에서 위도 차이에 따른 0.0036의 경도가 얼마의 거리를 나타내는지 계산해봄으로써 알 수 있다. 서울의 최남단 위도(37.698132° N)와 최북단의 위도(37.424783° N)를 각각 적용하여 거리를 계산해보면 아래와 같다.

UpKoDah google grid seoul.png
Google Earth 서울의 그리드



서울 최북단 (37.698132° N, 127.017891° E)
경도 127.014291°E (-0.0036)에 대한 Vincenty's Inverse 계산 결과: 317.489 (m)

서울 최남단 (37.424783° N, 127.059939° E)
경도 127.056339°E (-0.0036)에 대한 Vincenty's Inverse 계산 결과: 318.651 (m)

위와 같은 결과를 볼 때, 0.5° 정도의 위도 차이를 가진 서울 내에서, 경도 차이가 적은 두 지점의 비교는 무시 가능한 차이를 보임을 알 수 있다.

시스템 설계:클라우드 서버 구성

Micro-Service Architecture 개념

MSA(Micro-Service Architecture)는 큰 애플리케이션을 여러 개의 작은 애플리케이션으로 나눠 만드는 아키텍쳐이다. 개발, 빌드, 테스트 시간을 단축할 수 있으며 본 프로젝트에서처럼 여러 개의 서버를 서로 다른 언어, 프레임워크로 사용할 수 있다는 점에서 유연성이 굉장히 높다. 또한, scaling하기에도 용이하기 때문에 트래픽이 높은 서버에 적합하다.

MicroArchitecture 구성 요소

1. Upkodah API
upkodah 모바일 애플리케이션이 데이터를 얻기 위한 Application Programming Interface 프로그램이다. 사용자가 원하는 정보에 접근할 수 있도록 도와주는 중개 역할을 한다.

2. Upkodah Crawler
upkodah에서 사용하는 부동산 매물들을 다방으로부터 크롤링하여 데이터베이스에 적재하는 프로그램이다.

3. Upkodah Service
upkodah의 DB로부터 사용자가 원하는 조건에 맞는 매물을 검색하기 위한 프로그램이다.

4. Upkodah Mysql Database
upkodah의 매물 정보와 검색 정보, 그리고 편의시설 정보를 가지고 있는 데이터베이스

MicroArchitecture 설계 및 운영를 위한 플랫폼

1. Google Cloud Build

앱의 코드를 올려 Google Cloud상에서 Docker Image를 Build한 후 Google Container Registry에 등록해주는 클라우드 플랫폼이다. Google Container Registry에 등록된 이미지는 GKE 안에서 자유롭게 사용할 수 있다.

UpKoDah gcloud build.jpg


UpKoDah gcloud process.jpg



2. Google CloudSQL

안정성 있는 Mysql 데이터베이스를 실행할 수 있는 클라우드 플랫폼으로, 보안성과 고가용성의 특징을 가진다. Google Cloud Platform에서 CloudSQL proxy의 Docker Image를 제공하기 때문에 파드(Pod) 안에 CloudSQL proxy를 sidecar pattern으로 배포하면 앱에서 localhost로 DB 접근이 가능하다.

UpKoDah gcloud sql.jpg
3. Google Kubernetes Engine

MicroArchitecture를 구성하기 위한 클라우드 플랫폼으로, 마스터와 워커 VM노드로 구성된다. 마스터 노드의 api-server를 통해 각 노드가 통신을 한다. 각각의 앱들을 pod안의 컨테이너 형태로 배포할 수 있고, 파드에 문제가 발생 시 컨테이너만 옮겨 실행하면 된다. 스케일 조절이 간편하다. 고가용성과 확장성, 그리고 탄력성있는 MicroArchitecture 설계가 가능하다.

UpKoDah gcloud k8s engine.jpg


UpKoDah gcloud process2.jpg



MicroArchitecture 설계 내용

  1. GKE Cluster 안에서 Namespace로 Crawler와 API & Service를 분리
  2. Crawler의 경우 CronJob 형식으로 배포하여 매일 오전 2:00 ~ 6:00에 다방 매물을 크롤링하여 데이터베이스를 업데이트
  3. API의 경우 Deployment 형식으로 replicaset을 3개로 배포한 후 LoadBalancer Service 연결API에서 검색을 실행하기 위해서는 Service를 호출. 단순한 CRUD 연산은 CloudSQL proxy를 통해서 DB에 직접 접근
  4. Service의 경우 Deployment 형식으로 replicaset을 5개로 배포한 후 LoadBalancer Service 연결 CloudSQL proxy를 사이드카(sidecar) 패턴으로 배포하여 데이터베이스 접근


UpKoDah gcloud architecture.jpg



MicroArchitecture 배포 방식

  1. setup.sh -> CloudSQL proxy를 위한 서비스 계정 연동을 자동화한 코드
  2. build_and_deploy.sh -> 변경된 소스코드를 Cloud Build에 제출 후 Build된 Docker Image를 GKE의 Deployment에 적용시키는 자동화 코드

시스템 설계:서버-애플리케이션 연계

애플리케이션과 운영 서버의 연계 방식을 나타내는 유스케이스 다이어그램은 다음과 같다.

UpKoDah 서버애플리케이션연계.png



상황 서버 송신 내용
1. 애플리케이션이 실행될 때 편의시설 태그 매핑 정보를 전송한다.
2. 사용자가 매물을 검색할 때 검색된 모든 매물의 Shortcut을 전송한다.
3. 사용자가 매물 상세 정보를 볼 때 선택된 매물의 상세 정보를 전송한다.

각 상황별 송수신 상세는 다음과 같다. ※ 참고 : 서버 IP는 유동적이므로 생략한다.

송수신 명세:공통 반환값

▷ Response (JSON)

Name Type 설명
status String status가 'success'가 아닐 경우, 요청 오류
data JSON Object 요청 결과


송수신 명세:애플리케이션이 실행될 때

편의시설 태그 매핑 정보를 수신받을 때의 송수신 명세

▷ URL

https://{SERVER_IP}/v1/settings/

▷ Response (JSON)

Name Type 설명
code String 편의시설을 분류하는 코드. 카카오 API 호출 용도 및 내부 구분용으로 사용
type Integer 편의시설을 검색할 때, 카카오 API에 '카테고리'로 검색해야 하는 경우는 0, '키워드'로 검색해야하는 경우는 1
name String 편의시설의 표시 이름
icon String 편의시설의 아이콘 URL


송수신 명세:사용자가 매물을 검색할 때

검색된 모든 매물의 Shortcut을 전송할 때의 송수신 명세

▷ URL

https://{SERVER_IP}/v1/rooms/


▷ Parameter

Name Type 설명
longitude Double 검색 기준이 될 목적지의 경도
latitude Double 검색 기준이 될 목적지의 위도
limit_time Integer 매물부터 목적지까지 도달하는 데 걸리는 제한 시간 (분 단위)
estate_type Integer 매물의 방 타입
0 : 원룸
1 : 투룸
2 : 오피스텔
trade_type Integer 매물의 거래 타입
0 : 월세
1 : 전세
2 : 매매
facilities (Optional) String Array 사용자가 검색 조건으로 선택한 편의시설 코드의 배열.
편의시설 코드는 애플리케이션 초기화 단계에서 받은 데이터


▷ Response (JSON)

Name Type 설명
grids Double 검색된 전체 Grid를 담는 JSON 오브젝트
longitude Double 검색 기준이 될 목적지의 경도
latitude Int 검색 기준이 될 목적지의 위도
estate_type Int 매물의 방 타입
0 : 원룸
1 : 투룸
2 : 오피스텔
trade_type Int 매물의 거래 타입
0 : 월세
1 : 전세
2 : 매매


▷ Response (매물 Shortcut의 JSON)

Name Type 설명
id Double 매물의 ID
gridId Double 매물이 속한 Grid의 ID
latitude Int 매물의 위도
longitude Int 매물의 경도
estateType Int 매물의 종류
tradeType String Array 매물의 거래 타입
title JSON Array 제목
price Int 가격
deposit Int 보증금
floorStr String
realSize Double 제곱미터 면적
roughsize Double 평 면적
facilities String Array 주변 편의시설 코드
imgUrls String Array 이미지 URL
address String 지번주소
roadAddress String 도로명주소

송수신 명세:사용자가 매물을 검색할 때(상세정보 요청)

선택된 매물의 상세 정보를 전송할 때의 송수신 명세

▷ URL

https://{SERVER_IP}/v1/room/{Room ID}/info


▷ Response (JSON)

Name Type 설명
id Double 매물의 ID
gridId Double 매물이 속한 Grid의 ID
latitude Int 매물의 위도
longitude Int 매물의 경도
estateType Int 매물의 종류
tradeType String Array 매물의 거래 타입
title JSON Array 제목
price Int 가격
deposit Int 보증금
floorStr String
realSize Double 제곱미터 면적
roughsize Double 평 면적
facilities String Array 주변 편의시설 코드
imgUrls String Array 이미지 URL
address String 지번주소
roadAddress String 도로명주소
describe String 설명
isAnimal Boolean 반려동물 가능 여부
isBalcony Boolean 발코니 여부
isElevator Boolean 엘리베이터 여부
bathNum Int 화장실 수
bedNum Int 방 수
direct String 창 방향
heatType String 난방 방식
totalCost String 총 유지비
phoneNum String 전화번호

소프트웨어 설계:애플리케이션

설계 사양

UpKoDah 안드로이드이미지.png
UpKoDah 안드로이드스튜디오.png
Android OS Version 7 (Nougat) (Target : Android 11) 개발 도구 : Android Studio
(https://developer.android.com/studio)

패키지 구분

애플리케이션의 기본 패키지 경로는 다음과 같다.

Package Name : com.uos.upkodah
패키지명 설명
.data 지역 정보 데이터, 편의시설 데이터, 사용자 입력 데이터 등, 애플리케이션 내부에서 사용하는 데이터 클래스를 정의한 패키지
  • PositionInformation : 애플리케이션 내에서 활용하는 모든 주소 정보의 상위 클래스
  • UserPositionInformation : 사용자에게 출력시키기 위해 좌표 정보가 들어왔을 때, 이를 외부 API를 활용해 주소로 변환시켜 자동으로 주소를 완성시키는 기능을 가진 클래스
  • CompositePositionInformation : 여러 PositionInformation을 포함시킬 수 있는 복합체 클래스. 이 클래스로 정의된 파생 클래스는 GuRegionInformation(구 정보 저장), DongRegionInformation(동 정보 저장), GridRegionInformation(Grid 정보 저장)
.data.gps 위치정보 관련된 데이터, 위치정보 권한 조절 클래스를 정의한 패키지.
  • GeoCoordinate : 위도와 경도값을 반환할 수 있는 인터페이스
  • GeoCoordinateUtil : 위도와 경도값만 가진 객체를 만들거나, 각종 변환을 위해 사용되는 정적 메소드 집합 클래스
  • DegreeMinSec : 위도와 경도값을 실수형이 아니라 (도,분,초)로 정의하는 클래스.
  • GPSPermissionManager : 기기의 GPS 정보에 접근하기 위해 사용하는 클래스
.data.estate
  • Room : 매물의 정보를 가지고, 반환할 수 있음을 나타내는 인터페이스. EstateInformation을 구성할 때 활용한다.
  • EstateInformation : 매물 정보를 저장하는 위치 정보 클래스
  • FacilityInformation : 편의시설 정보에 대하여 편의시설의 위치와 아이콘만을 담는 클래스. 이 클래스는 매물 상세보기에서 매물 주변 편의시설을 지도에 보여줄 때만 사용한다.
  • Facility : 편의시설의 코드, 아이콘, 이름, 이미지 URL를 담아 저장하고, 특정 좌표를 입력하면, 해당 좌표 주변의 FacilityInformation 리스트를 가져오는 클래스.
.dialog 애플리케이션 내에서 사용하는 각종 대화상자 정의
  • LoadingDialog : 로딩 이미지를 출력시키고, 종료 신호가 오면 로딩을 종료하는 대화상자 클래스
  • SelectItemDialog : 사용자에게 리스트 내에서 선택할 수 있는 대화상자를 보여주고, 선택 결과를 출력하는 다이얼로그
.dialog.activity 애플리케이션 내에서 사용하는 Activity 형식의 대화상자 정의
  • SelectLocationDialogActivity : 지도에서 원하는 위치를 검색, 선택하며, 그 결과를 출력하는 대화상자
  • ShowLocationDialogActivity : 지도에 지정된 위치 정보들을 출력시키는 대화상자
.fragment.facilities 편의시설 정보를 표시하는 Fragment 클래스를 정의한다.
.fragment.image 매물 상세 정보 보기에서, 이미지 Pager 기능을 제공하는 Fragment를 정의한다.
.fragment.list 임의의 리스트를 표시하는 Fragment 클래스를 정의한다. 이 애플리케이션에서는 매물 정보를 출력할 때 활용하였다.
.fragment.map GoogleMAPS API를 활용한 지도를 출력시키기 위한 Fragment를 정의한다.
  • GoogleMapDrawable : GeoCoordinate 객체를 상속하여 지도에 그릴 수 있는 객체를 나타내는 인터페이스. 지도에 그릴 수 있는 모든 객체는 해당 인터페이스를 정의해야 한다.
.fragment.optionBar 아이콘과 텍스트 박스를 표시하여 사용자의 옵션 입력을 받는 용도로 활용하는 Fragment를 정의한다.
.fragment.searchBar 아이콘과 텍스트 박스, 그리고 검색 버튼을 표시하여 사용자의 검색 정보를 받는 용도로 활용하는 Fragment를 정의한다.

이 Fragment는 메인 화면과 SelectLocationDialogActivity에 활용하였다.

.server.extern 외부 서버에 HTTP 요청을 할 때 사용하는 요청 클래스들이 정의되어 있다.
  • CoordToAddrRequest : 좌표 정보를 주소 정보로 변환 요청한다.
  • CoordToRegionRequest : 좌표 정보를 지역 정보로 변환 요청한다.
  • SearchAddrRequest : 주소를 입력하여 해당 주소에 대한 정보를 가져오도록 요청한다.
  • SearchCategoryRequest : 카카오 로컬 API의 카테고리 검색을 하여 카테고리에 맞는 지역 정보를 가져오도록 요청한다.
  • SearchKeywordRequest : 카카오 로컬 API의 키워드 검색을 하여 키워드에 맞는 지역 정보를 가져오도록 요청한다.
.server.ukd 엎코닿 내부 서버에 HTTP 요청을 할 때 사용하는 요청 클래스들이 정의되어 있다.
  • EstateSearchRequest : 매물에 대한 정보를 가져오도록 요청한다. 매물 검색이나 매물 상세 정보 반환때 사용한다.
  • FacilitiesFilterRequest : 편의시설 필터 정보에 대한 애플리케이션 초기화 정보를 가져올 때 사용한다.
.util 애플리케이션 내에서 각종 개발 편의를 위해 사용되는 클래스 집합
  • JSONUtil : 오류 없이 JSON 오브젝트를 읽을 때 활용하는 정적 메소드 집합을 정의하는 클래스
  • PermissionRequringOnClickListener : 특정 버튼을 누를 때, 지정된 권한을 확인하고, 해당 권한이 없으면 실행을 중단시키는 리스너
  • GridIDToCoord : Grid ID를 GeoCoordinate 객체로 반환하는 클래스
  • WaitAndStart : 지정된 동작을 수행하고, 지정된 시간을 대기한 후, 동작 수행이 완료되었을 경우, 핸들러가 필요한 설정된 동작을 수행하는 클래스. 이 클래스는 SplashActivity에서 편의시설 정보를 받아올 때까지 3초 이상 대기하도록 할 때 사용하였다.
  • BitmapIconManager : 애플리케이션 내에서 지도에 표시하게 될 Icon 정보를 캐싱하기 위한 단일체 클래스
.viewmodel 애플리케이션의 기본 화면 구성인 SplashActivity, UkdMainActivity, SelectEstateActivity, ShowEstateActivity의 ViewModel 클래스를 정의하는 패키지

Activity 정보

화면 개발 단위인 Activity는 기본적으로 총 4가지가 정의되었으며, 추가로 대화상자 형태로 작은 단위의 Activity 2개를 정의하였다. 6개의 Activity의 역할은 다음과 같다.

Activity 클래스 이름 설명
SplashActivity 애플리케이션의 아이콘을 표시함과 동시에 애플리케이션 편의시설 초기화 정보를 가져오는 Activity
UkdMainActivity 사용자의 매물 검색 정보를 입력받는 메인 Activity

[장착된 Fragment]

  • SearchBarFragment
  • SearchOptionFragment
  • FacilitiesFragment
SelectEstateActivity 사용자의 검색 결과 매물을 지도와 리스트에 보여주는 Activity

[장착된 Fragment]

  • SelectionListFragment
  • GoogleMapFragment
ShowEstateActivity 사용자가 상세 보기를 요청한 매물의 상세 정보를 보여주는 Activity

[장착된 Fragment]

  • ImagePagerFragment
  • FacilitiesFragment
  • GoogleMapFragment
SelectLocationDialogActivity 사용자가 위치를 검색하고, 지도에서 위치를 선택하면 그 위치에 해당하는 PositionInformation 객체를 반환하는 클래스

[장착된 Fragment]

  • SearchBarFragment
  • GoogleMapFragment
ShowLocationDialogActivity 사용자에게 단순히 지도와 지도 내의 위치 정보들을 보여줄 때 사용하는 Activity. 매물 상세 보기에서 매물의 자세한 위치와 주변 편의시설 정보를 사용자에게 확인시켜주는 용도로 활용한다.

[장착된 Fragment]

  • GoogleMapFragment

외부 API 활용

‘build.gradle(Module)’파일에 기본 정의 외에 추가로 연결된 의존성 및 활용한 외부 API는 다음과 같다.

외부 API 이름 설명 및 용도
Volley 라이브러리

(Apache License 2.0)

안드로이드 내에서는 Apache HTTP의 사용이 시스템적으로 제한되기 때문에 HTTP 요청을 위해 Volley 라이브러리를 사용하도록 권장하고 있다.

이 라이브러리는 애플리케이션 내에서 모든 HTTP GET 요청을 위해 사용한다.

(https://developer.android.com/training/volley?hl=ko)

GSON 라이브러리

(Apache License 2.0)

객체의 JSON 변환, JSON의 객체 변환 시 사용한다. 서버 통신에서 JSON 형식으로 주고받기 때문에 사용하는 의존성

(https://github.com/google/gson)

Glide 라이브러리

(Apache License 2.0)

네트워크 이미지 리소스, 로컬 이미지 리소스를 View에 안정적으로 적용시키기 위한 라이브러리

(https://github.com/bumptech/glide)

[연관 클래스]

  • Facility
  • ShowEstateActivity
Google MAPS 라이브러리

(Apache License 2.0)

구글 지도 API를 사용하기 위한 의존성

(https://developers.google.com/maps/)

[연관 클래스]

  • GoogleMapFragment
Kakao 로컬

키워드로 장소 검색

키워드로 장소를 검색하는 Restful API. 지도에서 사용자가 목적지를 검색하거나, 특정 위치 주변의 편의시설을 검색하여 보여줄 때 활용한다.

[연관 클래스]

  • SearchKeywordRequest
  • SearchKeywordParser
  • Facility
  • SelectLocationDialogActivity
Kakao 로컬

카테고리로 장소 검색

카테고리로 장소를 검색하는 Restful API. 특정 위치 주변의 편의시설을 검색하여 보여줄 때 활용한다.

[연관 클래스]

  • SearchCategoryRequest
  • SearchCategoryParser
  • Facility
Kakao 로컬

좌표로 주소 변환하기

좌표값을 주소로 변환하는 Restful API. 사용자 자신의 위치를 가져올 경우, 위도와 경도값밖에 얻을 수 없어, 이를 사용자에게 보여줄 수 있는 주소로 변환할 때 사용한다.

[연관 클래스]

  • CoordToAddrRequest
  • CoordToAddrParser
  • UserPositionInformation
Kakao 로컬

좌표로 행정구역정보 받기

좌표값을 이용해 해당 좌표의 행정구역 정보를 가져오는 Restful API. 서버에서 받은 매물들을 구, 동 단위로 분류하여 지도에 보여줄 때 사용한다.

[연관 클래스]

  • CoordToRegionRequest
  • CoordToRegionParser
  • EstateClassifier

지도 API 적용 방법 - GoogleMapFragment

com.uos.upkodah.fragment.map 패키지는 지도에 특정 객체를 그리고 지도를 보여주기 위한 클래스다.

  • a. 초기화
    GoogleMapFragment를 Activity나 Fragment의 onAttachFragment 메소드에 넣는다.
메소드 설명
void setData(GoogleMapData data) GoogleMap의 데이터를 관리하는 GoogleMapData 객체를 외부에서 설정할 때 사용한다.
GoogleMapData getData(GoogleMapData data) 디폴트 GoogleMapData 객체를 가져온다.
  • b. GoogleMapData 조작
    GoogleMapFragment에 연결된 GoogleMapData 객체를 조작하여 지도의 상태, 아이콘 등을 읽을 수 있다.
메소드 설명
void setMapMarkers(List<? extends GoogleMapDrawable> mapMarkers) 지도의 마커를 모두 초기화한 후, 지도에 GoogleMapDrawable 객체 리스트를 넣어 마커를 재설정한다.
void setMapMarker(GoogleMapDrawable mapMarker) 지도의 마커를 모두 초기화한 후, 지도에 GoogleMapDrawable 객체를 넣어 마커를 재설정한다.
void addMapMarker(GoogleMapDrawable mapMarker) 지도에 지정된 마커를 추가한다.
void setZoomLevel(float zoomLevel) 지도의 줌 레벨을 실수를 이용해 설정한다.
float getZoomLevel() 지도의 줌 레벨 실수값을 반환한다.
void setZoomLevelWithDepth(int depth) 지도의 줌 레벨을 깊이 단위로 설정한다. 깊이 단위는 0,1,2를 받을 수 있다.
0: 구 단위
1: 동 단위
2: Grid 단위
int getZoomDepth() 지도의 줌 레벨 깊이값을 반환한다.
void setCenter(GeoCoordinate coordinate) 지도의 중심점을 지정 좌표, GeoCoordinate 객체로 설정한다.
void setCenterUsingPositions() 지도에 들어간 마커들의 평균 중심점으로 지도의 중앙 좌표를 바꾼다. 마커가 없다면 초기 위치로 설정한다.
void setZoomListener(ZoomListener listener) 지도에 줌이 변할 때 호출되는 리스너를 추가한다.
void setMarkerListener(MarkerListener listener) 지도에 마커를 누르거나, 마커 윈도를 누를 때 호출되는 리스너를 추가한다.
  • c. GoogleMapDrawable extends GeoCoordinate
    지도에 표시할 마커 인터페이스다. 마커를 표시하려면 해당 인터페이스를 정의하면 된다.
메소드 설명
String getMarkerWindowTitle() 마커를 선택했을 때 마커윈도에서 보여줄 제목.
String getMarkerWindowSnippet() 마커를 선택했을 때 마커윈도에서 보여줄 부제목.
String getIconBitmapKey() BitmapIconManager 객체에서 가져올 아이콘 비트맵의 키.
boolean isSelectedMarkerInit() 해당 마커가 초기에 선택된 상태로 표시되어야 할 때 이 메소드의 출력값을 true로 한다.
  • d. GeoCoordinate
    위도와 경도값을 반환할 수 있는 객체는 해당 인터페이스를 장착시킨다.
메소드 설명
double getLongitude() 해당 객체의 경도 좌표를 가져온다.
double getLatitute() 해당 객체의 위도 좌표를 가져온다.
GeoCoordinate GeoCoordinateUtil.getInstance(double longitude, double latitude) 해당 위도와 경도를 갖는 GeoCoordinate 객체를 생성한다. 이 객체는 좌표값만 반환할 수 있고, 어떠한 기능도 수행하지 않는다.
  • e. 사용 예제

UpKoDah 지도사용예제코드.png

앱 실행 및 스플래시 화면 시퀀스 다이어그램

앱을 실행시키면 스플래시 화면이 표출되고, 서버로부터 편의시설 정보를 받아 초기화한다.

UpKoDah app sequence 1 splash.jpg



메인 화면 전환 및 표시 시퀀스 다이어그램

스플래시 화면이 끝나면 메인 화면을 생성하며, 메인 화면의 초기 설정은 다음과 같다.


UpKoDah app sequence 1 splash.jpg



여기서, SearchInputObjects는 다음 표와 같다.

SearchInputObjects class
목적지 설정을 위한 프래그먼트 SearchBarFragment
제한 시간 선택을 위한 프래그먼트 SearchOptionFragment
매물 타입 선택을 위한 프래그먼트 SearchOptionFragment
거래 타입 선택을 위한 프래그먼트 SearchOptionFragment

검색 목적지 설정 시퀀스 다이어그램

사용자가 검색 목적지를 선택하는 방법은 두 가지다.

a. 사용자 자신의 현재 위치로 설정
b. 지도에서 목적지를 선택

다음 유형이 설정되면 시퀀스 다이어그램의 흐름대로 검색을 수행한다.


UpKoDah app sequence 3 input.jpg



매물 검색 요청 시퀀스 다이어그램

사용자의 검색 요청에 의해 서버로 요청이 들어가고, 이를 반환하여 저장하는 과정이다.


UpKoDah app sequence 4 request.jpg



검색 결과를 EstateSearchResult 단일체 객체에 저장하는데, 일반적으로 액티비티 간 데이터 통신은 Intent를 이용한 Parcelable 송수신이 기본이지만, 매물 용량이 과대한 경우 이를 수용할 수 없어 단일체 객체에 별도로 저장하도록 한다.

검색 매물 지도 표시 시퀀스 다이어그램

검색된 매물을 지도에 표시하는 시퀀스 다이어그램이다.


UpKoDah app sequence 5 display.jpg



입력 결과를 가져와 EstateInformation 객체를 생성하고, EstateClassifier에 넣어 구, 동, Grid 단위로 분류하여 지도에 표시할 준비를 한다. EstateClassifier 객체는 KakaoLocalAPI에 각 EstateInformation 객체의 지역 정보를 설정하도록 요청하고, 지역 정보 설정이 완료되면 지역 정보를 보고 분류한다. 분류가 끝나면 결과를 저장하며, 줌 수준에 따라 GoogleMapFragment에 넣어 결과를 지도에 보여주게 된다.

참고로, 여기에서 보이는 EstateInformation은 지도와 리스트에 표시하기 위한 Shortcut 정보만 넘어온 상태라 매물을 선택하여 상세 사항을 볼 때, Shortcut 정보의 RoomID를 서버에 다시 요청하여 상세정보를 가져와야 한다.

매물 상세정보 보기 시퀀스 다이어그램

매물의 상세정보를 볼 때는 EstateInformation이 가진 RoomID를 서버에 재요청하여 매물에 대한 상세정보를 모두 가져온다.


UpKoDah app sequence 6 detail.jpg



소프트웨어 설계:크롤링 및 데이터 가공

매물을 표현할 수 있는 정보들을 수집하고, 기능의 구현에 필요한 데이터를 수집 및 가공하여 데이터베이스에 저장한다.

UpKoDah crawler.jpg



크롤러

(https://github.com/upkodah/item-crawler/tree/main/dabapi)

웹에 접근하기 편한 다방을 이용하여 크롤러를 구현함. 일차적으로 서울 전역에 대한 요청에서 지역 단위의 정보와 id 목록을 얻어오고, id 목록 중 매물이 존재하는 것을 확인하는 2차 검증을 했다. 이후 세부 정보 요청에서 구현에 필요한 정보들을 수집한다.

UpKoDah dabang01.jpg UpKoDah dabang02.jpg
다방 '방찾기' 페이지 multiroom request와 bbox request



다방에서는 서버에 요청을 보내는 방식으로 매물을 표시하여 본 앱에서도 아래와 같은 요청을 선택하여 사용했다.

(1) www.dabangapp.com/api/3/marker/multi-room?
(2) www.dabangapp.com/api/3/room/list/multi-room/bbox?
(3) www.dabangapp.com/api/3/room/detail2?



UpKoDah dabapi.jpg


위 세 요청 중 앞선 2개의 요청에서 본 앱의 크롤링 대상인 서울 전역의 매물의 간단한 정보를 수집하였고, 이때 얻은 정보로 세 번째 요청을 보내어 세부 정보 응답을 얻어냈다. 이 응답은 JSON 형태로 되어 있으며, Python 환경의 크롤링 컨테이너에서는 이 응답을 파싱하여 필요한 정보들을 저장한다. 데이터의 저장방식에 대해서는 데이터베이스 모델에서 논한다.

아래는 크롤링을 수행하는 API의 간략한 기능 설명이다.

item-crawler/dabapi/
클래스/메소드 설명
MultiRoom (request_id.py) 서울 전역에 대하여 multi-room 요청을 수행하여 전체 정보를 받아온다. regions 정보와 전체 id_list를 생성한다.
Bbox (request_id.py) MultiRoom에서 생성된 regions 정보와 id_list 정보를 바탕으로 원하는 지역의 id list를 생성한다. 본 앱에서는 서울 전역을 대상으로 함.
Detail (request_info.py) bbox request를 통해 얻은 id list에 대하여 매물 정보를 받아 온다.
filter.py, dabapi_const.py 요청의 필터 포맷과 필요한 상수 정보들을 저장


데이터를 크롤링하는 과정 이후에는 가져온 정보를 편집하고 주 기능을 구현하는 데에 필요한 정보들을 추가하여 데이터를 가공하는 과정이 필요하다.

편의시설 메타 정보

(https://github.com/upkodah/item-crawler/tree/main/kakaolocal)

편의시설의 정보는 카카오 로컬 API의 카테고리 검색과 키워드 검색 기능을 통해 획득한다. 사전에 논의된 은행, 카페, 병원 등의 정보는 카테고리 검색 기능을 통해 얻고, 카테고리 검색 기능에 포함되지 않은 운동 시설, 세탁소, 경찰서 등의 정보를 키워드 검색 요청을 수행하도록 하였다.

주 기능으로 편의시설에 따른 점수를 재기 위하여 데이터 가공 부분에서는 매물이 등록될 때마다 편의시설의 유무에 대한 정보를 기록한다. 이후 편의시설 추천을 도입하기 위해 편의시설의 거리와 수, 신뢰성 등의 메타 정보를 기록하기로 했다. 그리고 앱 상에서 편의시설의 정보를 지도에 표현하기 위해 데이터베이스에서 불러온 편의시설의 메타 정보로 해당 매물에 대한 API 요청을 선택적으로 할 수 있도록 하였다.

item_crawler/kakaolocal/
클래스/메소드 설명
Facility (request_facility.py) 카카오 로컬 API를 수행, 편의시설 목록에 따라 키워드와 카테고리를 자동으로 분류하여 질의하고 메타 정보를 생성한다.
klconst.py, klerror.py 쿼리에 해당하는 키워드, 카테고리의 목록을 저장하는 상수와 그 밖의 상수, 에러들을 포함.


그리드 시스템

(https://github.com/upkodah/item-crawler/tree/main/grid)

대부분의 부동산 애플리케이션에서는 부동산 매물 정보의 표현에 있어 가시성과 소프트웨어 응답성을 높이기 위해 클러스터링된 데이터 표현을 사용한다. 기본적으로는 행정구역을 적용하고, 더 낮은 수준으로는 아파트 단지 등의 클러스터 수준을 제공한다(네이버 부동산). 본 앱에서는 단지 정보를 갖기 어려웠으므로 이를 제공하기 위해 그리드를 도입하였다.

그리드의 기준이 될 좌표를 정하고 그 주변에서 거리에 대한 그리드의 단위 좌표 크기를 구한다. WGS84 시스템에서 사용하는 중점 좌표를 사용할 수도 있고, 서울에 대해 정확도가 더 올라가도록 서울의 중앙 좌표를 기준으로 사용할 수 있으나, 서울 내에 대한 차이는 별로 크지 않으므로 서울시립대학교의 좌표를 기준점으로 하여 약 400m 거리를 단위 크기로 하여 그리드를 나누도록 했다. 자세한 계산은 ‘2.5 이론적 계산 및 시뮬레이션’ 부분에서 서술한다.

이 게산을 통해 대한민국이 포함된 사각형 그리드에는 경도로 1500여 개, 위도로는 3400여 개의 그리드로 나뉘게 되고, 서울 주변의 모든 지역에 8자리의 grid ID를 부여한다. 좌표 기준(동,서,남,북 극단과 그리드 기준좌표)과 Vincenty’s Formulae의 변환을 통해 나온 그리드 크기에 따라 그리드를 나눌 수 있도록 설계하였으며 앱과 서버에서 이를 통해 그리드 ID와 ID에 해당하는 그리드 지점의 중심 좌표를 얻도록 코드를 구현했다(get_grid_id(), grid_center).

UpKoDah grid.jpg UpKoDah grid design.jpg



item-crawler/grid/
클래스/메소드 설명
GeoGrid: (geogrid.py) 동서남북 극단 좌표와 그리드 기준좌표, 그리드 크기를 받아 그리드 체계를 초기화하는 클래스이다. 본 앱에서는 동일한 그리드 시스템을 사용하므로 사용의 편이를 위해 간략화할 수 있다.
GeoGrid: get_grid_id (geogrid.py) 경위도 좌표를 입력하여 그리드 ID를 반환하는 메소드
GeoGrid: grid_center (geogrid.py) 그리드 ID를 입력하여 해당 그리드의 중앙 좌표를 반환하는 메소드
geoconst.py, geoerror.py 기준좌표들의 디폴트 값, 에러 저장.


소프트웨어 설계:매물 검색 알고리즘

매물은 사용자로부터 입력받은 위치에서 사용자로부터 받은 시간 내로 갈 수 있는 범위 안에서 검색한다. 시간은 10분 단위로 나누어 검색하도록 설계하였다. 사용자로부터 입력받은 위치에서 버스와 지하철을 타고 환승을 하지 않고 갈 수 있는 범위만을 검색한다.

버스 정류장으로 갈 수 있는 결과 출력

사용자로부터 시간과 위치를 입력받아 그 위치에서 버스를 타고 환승하지 않은 상태에서 갈 수 있는 범위를 얻는다. 사용자의 편의를 위한 앱이므로 복잡하게 환승하여 가야하는 곳은 제외하고 환승 없이 가게 되는 곳만 검색하게 되었다. 입력받은 위치 주변의 버스 노선을 획득하여 이를 바탕으로 입력받은 정류장으로부터 어느 정류장까지 갈 수 있는지 검색하게 된다. 여기서 버스 노선에는 회차하는 노선도 포함되어 있으므로, 결과를 얻었을 때 이 정류장이 버스가 회차한 경우인지 검사한다. 단, 서울시로 제한하여 설계하는 앱이고 이에 따라 사용하는 API도 서울 지역을 지원하는 것으로 선택하였으므로 지원 범위 밖의 버스 노선도 존재한다. 갈 수 있는 정류장을 구하면 그 위치의 GPS를 통해 해당 위치가 어떤 그리드에 속해있는지 검색하여 그리드 값을 얻고 이 값을 통해 DB에 현재 그리드에 있는 매물들을 질의하게 된다.

사용하는 API는 다음과 같다.

1) 목적지 근처의 버스 정류장 찾기
https://www.data.go.kr/tcs/dss/selectApiDataDetailView.do?publicDataPk=15000759
GPS 좌표를 기반으로 근처의 버스 정류장의 GPS를 반환하는 공공 데이터 포털 Open API를 사용하여 사용자로부터 입력받은 위치 근방의 버스 정류장을 얻는다.


2) 버스 노선 데이터 받기
https://www.data.go.kr/tcs/dss/selectApiDataDetailView.do?publicDataPk=15000193
사용하게 될 버스 노선에 대한 데이터를 얻는다.


3) 두 버스 정류장 사이의 시간 구하기
https://www.data.go.kr/tcs/dss/selectApiDataDetailView.do?publicDataPk=15000414
목적지에서 가까운 버스 정류장과 목표로 하는 매물에 가까운 버스 정류장 사이의 이동 시간을 구하기 위해 이용한다. 환승을 고려하지 않고 가는 경우만을 생각하기 때문에 처음 탑승했던 버스 노선과 환승 횟수를 기준으로 필터링하여 원하는 목적지의 버스 정류장을 얻는다.

지하철로 갈 수 있는 결과 출력

사용자로부터 시간과 위치를 입력받아 그 위치에서 지하철을 타고 환승하지 않은 상태에서 갈 수 있는 범위를 얻는다. 여기서도 또한 환승을 하지 않고 갈 수 있는 곳만 검색한다. 지하철 노선에 대해서는 서울을 지나가는 모든 데이터를 얻을 수 있는 API가 없어 직접 노선을 제작하였다. 데이터의 형태는 [‘노선’, ‘지하철역 이름’, ‘ 다음 지하철역까지 걸리는 시간’]을 원소로 가지는 배열로 제작하였다. 서울을 지나는 모든 지하철 노선을 넣었고 주소가 서울로 되어 있는 지하철역만을 넣었고 그 외 지하철역의 주소가 경기로 바뀌는 역부터 데이터에서 제외하였다. 카카오 로컬 API를 통해 근방의 지하철역을 검색한 후 저장해둔 지하철 노선의 데이터를 통해 사용자로부터 입력받은 시간 내에 도착할 수 있는 지하철역을 검색하여 반환한다. 갈 수 있는 지하철역을 구하면 그 위치의 GPS를 통해 해당 위치가 어떤 그리드에 속해있는지 검색하여 그리드 값을 얻고 이 값을 통해 DB에 현재 그리드에 있는 매물들을 질의하게 된다.

사용한 API는 아래와 같다.

1) 목적지 근처의 지하철역 찾기
https://developers.kakao.com/docs/latest/ko/local/common
입력된 장소에서 가까운 지하철역을 검색하여 얻는 API이다.

소프트웨어 설계:데이터베이스 모델

현재 매물 정보에 대한 데이터베이스 모델은 아래와 같다.

UpKoDah db model.jpg

데이터베이스 모델


1) rooms, infos 테이블
두 테이블은 위에 서술된 데이터들을 담고 있는 테이블이다. ‘rooms’의 필드에서 기본적인 매물의 정보를 포함하며 앱에서 매물 리스트 디스플레이에 활용된다. 그리고 rooms 필드의 id에 연관된 room_id를 primary key로 사용하는 ‘infos’ 테이블은 매물의 상세정보를 포함한다.

2) facilities 테이블
편의시설의 정보를 담는다. rooms와 infos 테이블에서 다룰 편의시설 메타 정보의 기준이 되는 테이블로 만들었으며, 앱에서는 이 테이블 정보를 참조하여 편의시설 검색을 수행한다. 현재 지원하는 메타 정보는 편의시설의 유무 정보이다.

3) searches, items 테이블
주 기능 중 하나인 예상 도착 시간(ETA)에 따른 매물 탐색에서 API 사용량과 응답시간이 많아 이를 줄이기 위한 캐싱 데이터의 역할로 구성한 테이블이다. 사용자가 많은 도착 지점(e.g. 강남역, 대학교)에 대한 정보들을 저장하여 이 정보들을 선 검색하도록 하여 기능의 향상을 꾀하였다.

크롤링 데이터 저장

위와 같은 테이블을 기본적으로 갖고 있으며 rooms, infos 테이블을 주 테이블로 사용한다. 크롤링에 용이한 python을 사용하여 데이터를 가공하므로 이를 실행시키기 위해 메인 서버에서 이를 도커 컨테이너로 전개(deploy)한다. 데이터베이스는 메인 서버 환경에서 실행된 MySQL 서버로 이 컨테이너와 통신을 통해 데이터를 적재한다. python dict 형태로 모은 데이터를 MySQL query문으로 변경하는 과정을 거쳐 데이터를 재가공하고, DB 서버와 통신한다.

서버는 사용시간이 상대적으로 적을 것으로 예상되는 오전 2~6시 동안 크롤링을 수행하고 커밋한다. 기존에 있는 매물에 대해서는 update를 수행하고, 기존에 없는 새 매물에 대해서는 insert를 하는 방식으로 매물을 적재한다. 주 테이블 중 rooms의 필드를 먼저 등록하고 그 필드의 index(room_id)를 Primary Key로 연관된 infos 테이블에 상세정보 필드를 저장한다. 그리고 위에서 갱신되지 않은 매물 데이터에 대해서는 없는 매물로 취급하여 삭제 과정을 거친다.


item_crawler
기능 설명
format_info.py 매물의 raw data를 요청(detail, grid_id, facility 정보)하여 이를 모아 포매팅한다. rooms와 infos 테이블이 들어갈 정보들로 변형한다.
sql_query.py 크롤링된 매물 정보를 query 문으로 재가공한다. 조건에 맞는 SELECT, INSERT, UPDATE, DELETE 문을 생성한다.
main.py 도커 컨테이너가 실행될 때 실행될 main 파일이다. sql_query.py의 메소드를 사용하여 위에 설명한 적재과정을 수행한다.
Dockerfile
build.sh, build_and_submit.sh
deploy.sh (+ /deploy)
도커 컨테이너의 빌드 및 디플로이에 사용되며 이 과정을 자동화한다.

결과 및 평가

완료 작품의 소개

프로토타입

UpKoDah app01 main.png

메인 화면

UpKoDah app03 option.png

매물 타입 선택

UpKoDah app02 maps.png

지도에서 목적지 선택

UpKoDah app04 loading.png

검색 결과 로딩

UpKoDah app05 cluster01.png

검색 결과 구 단위 표시

UpKoDah app06 cluster02.png

검색 결과 동 단위 표시

UpKoDah app07 list.png

검색된 매물 리스트

UpKodah app08 detail.png

검색된 매물 상세 정보

UpKoDah App09 facility.png

검색된 매물 주변 정보 표시

작동 설명

UpKoDah app contents control.png
메인 페이지 작동 설명

UpKoDah app contents view.png
지도 및 매물 리스트 페이지

UpKoDah app contents view detail.png
상세 페이지, 편의시설 페이지



관련사업비 내역서

개발비용 내역서 (단위: 원)
항 목
(품명, 규격)
단 가 비 고




와이어프레임 및 디자인 외주 90,000
도메인 비용 30,000
구글 플레이 개발자 등록 27,000 ($25)
공간 사용 등 78,600
가상 서버 호스팅 비용(2~3개월) 170,000
합 계 395,600

완료작품의 평가

평가 결과

평가 항목 평가 방법 적용 기준 개발 목표치 비중(%) 평가 결과
1.응답시간 사용자 입력에 대해 적절한 반응시간과 처리시간을 갖는가
  • 사용자 입력에 대한 반응 속도 테스트
5초 이내 15% 80
2.신뢰성 예외 상황이 발생하더라도 오류 없이 수행하며, 정확하고 일관된 결과를 제공하는가
  • 서버 연결에 실패했을 때 올바르게 오류가 처리되는가
  • 일반 사용자 환경에서 오류가 발생하지 않는가
2개 20% 100
3.사용자 편의성 사용자가 이 프로그램을 사용할 때 쉽게 이해하고 쓸 수 있는가
  • 주 기능에 도달하기까지 과정이 복잡한가
  • 화면 별 UI가 일관성 있게 작성되었는가
  • 결과를 지도 등을 통해 직관적으로 보여주는가
3개 25% 100
4.유지보수성 결함이 발생하거나 새로운 기능 추가가 필요할 때, 수정이 쉽게 이루어질 수 있는가
  • 애플리케이션과 서버 간 결합도가 여러 플랫폼을 수용할 수 있는가
  • 작성된 프로그램 코드가 이해하기 쉽게 짜여져 있는가
2개 10% 75
5.콘텐츠 적합성 프로그램이 설계 목적에 맞게 정보를 적절하게 사용자에게 출력하는가
  • 사용자가 장소를 검색했을 때, 교통 편의(직통 노선)을 고려한 결과가 정상적으로 출력되는가
  • 이동 시간을 고려한 매물 검색이 가능한가
  • 편의 시설 정보가 충분히 포함되어 있는가
  • 기타 계획된 추가 기능을 제공하고, 잘 작동하는가
기본 기능을 포함한 3개 30% 70

평가 상세

  1. 응답시간
    API 호출 횟수가 지나치게 많아 검색 시간이 다소 오래걸려 아쉬운 점이 있었다. 하지만, 캐싱을 통해 속도 문제를 충분히 개선할 수 있을 것으로 판단했다.
  2. 신뢰성
    신뢰성 테스트를 위해 애플리케이션 실행 과정에서 과하게 매물을 넣어보거나, 검색어를 넣지 않거나, 검색이 제대로 되지 않는 값을 넣었을 때 예외가 발생하지 않았다. 서버 연결에 실패했을 때도 연결 문제를 출력하도록 하였다.
  3. 사용자 편의성
    지도를 통한 매물 표시가 깔끔하고, 입력값을 넣는 것도 어렵지 않고 직관적이라고 판단하였다.
  4. 유지보수성
    현재 애플리케이션은 Android OS를 기준으로 만들어졌으나, 서버와의 통신 방식을 RestfulAPI 방식을 활용하여 HTTP 통신 및 JSON 송수신만 진행하므로 서버와 애플리케이션 간 결합도는 매우 낮다. 또한, 애플리케이션의 핵심 표출 기능인 지도 표출 기능을 캡슐화 하고, 뷰와 데이터 간 결합도를 낮추는 MVVM 방식을 채택하여 애플리케이션을 개발하였기 때문에 애플리케이션에 추가 기능을 넣는 것도 수월하다고 평가했다.
    다만, 샘플 매물 논의와 다수의 API 호출로 인한 알고리즘 논의가 길어지면서, 실질적인 개발 기간이 넉넉하지 않아 코드를 정리할 시간이 부족했던 탓에 코드의 가독성에 대해서는 낮은 평가를 받았다.
  5. 콘텐츠 적합성
    사용자가 원하는 검색 옵션을 넣고, 결과를 보여주는 것은 성공하였으나, 교통 정보를 제공하는 기능을 구현하지 못해 높은 평가를 주지는 못했다. 계획된 추가 기능은 구현하지 않았다.

향후계획

어려웠던 내용들

ETA 기반 길찾기 알고리즘 – API 사용량과 API 응답시간 문제

구현할 때, 사용해야 하는 정보의 양이 많아서 이를 공공 데이터 API에 의존해야 하는 본 앱의 특성상 어려움이 있었다. 질의해야 하는 양에 비해 API 사용량은 제한되어 있었으며, 알고리즘에서 API 응답시간이 차지하는 양이 많았다. 따라서 API를 사용하면서 얻은 데이터들을 수집하여 저장하고 이를 통해 쌓인 데이터를 토대로 질의를 먼저 수행하여 API 사용량을 줄이고 응답성을 높이고자 했다. 또 이것의 기본 데이터를 쌓기 위해서 API 트래픽이 적을 때, 목적지로 선정되기 쉬운 지역과 시간(고빈도 질의 조건)에 대한 질의 수행하도록 구현했다. 이 방식을 이용할 때 사용자가 증가할수록 사용자가 선호하는 지역과 시간의 정보를 얻을 수 있으리라 생각했다.


매물 확보 문제

본 애플리케이션의 기능은 목적지와 조건에 따른 매물들을 나타내는 것으로, 매물의 수가 적지 않아야 했다. 매물을 표현하기 위해선 실제 매물을 가져오는 방법과 가상의 매물을 보여주는 방법이 있으며, 가상의 매물을 보여주기에는 매물의 조건이 매우 다양하여 이를 소프트웨어에서 구현하기에 쉽지 않은 점이 있었다. 또한, 매물을 직접 구하는 방법으로 처음에는 부동산 매물이 공개되어 있어 쉽게 얻을 수 있을 것으로 예상했다. 하지만 부동산 중개업이 매물 정보를 자산으로 하는 사업이며 네이버 부동산이나 직방과 같은 부동산 정보 O2O 플랫폼도 해당 매물을 직접 중개할 수 없는 단순 광고 및 정보 매체임을 알게 되었다. 따라서 부동산 매물을 얻는 방법이 매우 한정되어 크롤링의 법적 한계에도 불구하고 앱을 검증하기 위해 타 웹 또는 앱에서 부동산 정보를 크롤링하기로 하였다.


애플리케이션 매물 지역 분류 지연

본 애플리케이션은 현재 서버에서 Grid 단위의 매물을 받아 구, 동 단위로 정렬하여 구 단위 및 동 단위로 묶어 보여주는 형태로 사용자에게 매물 분포 지도를 보여주게 된다. 이때, 매물에 지역 정보가 담겨있지 않아 검색된 매물 전체에 대해 좌표를 주소로 변환하는 API를 부르게 되는데, 매물 개수가 많아질 경우 이 부분에서 상당한 지연이 발생하는 것을 알 수 있었다.

차후 구현할 내용

UX 분석을 통한 검색 조건 추가

검색 조건에 가격대 검색이나 선호 대중교통 선택 등, 여러 옵션을 적용 가능하도록 한다. 다만, 이를 추가하려면 전세나 월세에 따라 입력 방식을 다르게 해야하며, 적절한 UI 선택을 위한 의논이 필요할 것으로 보인다.

목적지 다중 선택을 고려

목적지를 여러 위치를 골랐을 때도 여러 목적지에 가장 최적인 매물을 찾아낼 수 있는 기능에 대해서 초기에 논의된 바가 있다. 이 기능을 구현하려면 매물의 수가 지나치게 줄어드는 것을 방지하기 위해 단일 대중교통 위주의 현재 알고리즘의 수정이 필요하여 가능하다면 차후에 구현하는 것으로 하였다. 기존 알고리즘을 이용할 경우, 지정된 각 목적지 주변에 지나는 대중교통이 동시에 지나는 매물을 찾아야 하는데, 이 방법을 사용하면 실제 검색되는 매물 수는 매우 적거나, 특정 대중교통 인프라가 좋은 지역으로 쏠릴 가능성이 있어, 환승 횟수를 고려한 다양한 검색 방법이 필요할 것이다.

매물 관리자 페이지 제작

현재 매물을 관리하기 위한 관리자 페이지가 없어 초기에 샘플 매물을 작성할 때도 상당한 어려움이 있었다. 실질적으로 데이터 입력 역시 비전문 사용자가 진행하게 되기 때문에, 매물을 등록할 수 있는 페이지 작성, 그리고 등록된 매물을 관리할 수 있는 페이지 작성이 필요하다.

검색 범위 전국범위 확대

초기 계획은 검색 범위를 전국으로 확대하는 것이었다. 이를 구현하려면 전국범위의 대중교통의 노선 상세정보(소요 시간, 정류장 목록 및 위치)를 가지고 있어야 한다. 하지만, 서울시 이외에는 공공 데이터 중에 대중교통의 상세 노선 정보를 얻을 수 있는 API가 존재하지 않았다. 그 대안으로 ODSay 대중교통 API 같은 API가 제시되었으나, 실제 API 호출 횟수를 고려했을 때, 무료 사용 횟수가 적고, 확장 비용이 월 300만 원이므로 사용 여건이 되지 않았다. 차후 개발하게 된다면, 이러한 문제를 해결해야 할 것으로 본다.