![[Spring] 놀멍 서비스 개발 일지 - 지도 화면 개발하기1](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdXxNmO%2FbtsLFdZy87W%2Fy1kIh9w85MfAG9Ilqu4bYk%2Fimg.jpg)
이 글은 반려견 동반 가능 시설 공유 플랫폼 '놀멍'의 메인 화면인 지도를 개발하는 과정입니다.
위 앱은 네이버 지도로 지도에서 카페 카테고리를 선택하면 위 처럼 해당 화면 범위 내에 있는 카페에 대한 정보를 마커로 보여주고, 마커를 클릭하면 해당 카페에 대한 자세한 정보를 보여줍니다.
저희 놀멍 서비스도 위와 같이 지도 화면과 반려견 동반 가능 시설에 대한 정보를 마커로 제공해야 했습니다.
놀멍 지도의 요구사항
- 지도를 통해 장소 검색을 진행할 수 있다.
- 다양한 옵션(시설 종류, 견종 제한, 찜한 장소 등)을 통해 검색을 필터링할 수 있다.
초반에 마주한 문제
저희 `놀멍`은 Naver 지도를 사용하기로 계획하였고, 장소에 대한 정보 역시 Naver에서 제공하는 API를 활용하여 구현하고자 했습니다. 하지만 Naver에서 제공하는 API는 다음 3가지 문제가 있었습니다.
- API 호출량 제한(일 호출량 20만 쿼리로 제한)
- 부정확한 데이터(폐업한 시설이 여전히 운영 중이라고 응답하는 경우가 있음)
- 시설에 대한 부족한 정보(시설 이미지, 운영 시간 등 정보가 없는 경우가 있음)
물론 일일 20만 쿼리의 호출량 제한은 회원 수가 최소 몇십만 명은 되어야 문제가 되겠지만, 나머지 두 가지 문제로 인해 직접 데이터를 수집하기로 결정하였습니다.
데이터 수집 및 가공
저희는 공공데이터 포털에서 제공하는 전국 반려동물 동반 가능 문화시설 위치 데이터를 수집하였습니다.
전체 데이터의 수는 약 24000개가 있었고, 초기 서비스는 수도권을 중심으로 진행하기로 하여 서울, 경기, 인천의 데이터만을 남겼습니다.
그리고 여러 카테고리 중에서 동물 병원과 동물 약국은 저희 서비스의 취지에 맞지 않다고 판단하여, 최종적으로 524개의 장소 데이터를 남겼습니다.
원래는 540개 정도 데이터가 있었는데, 팀원들과 나눠서 각 장소가 현재 운영 중인지 일일히 확인했고, 최종적으로 524개의 데이터만 남게 되었습니다..😭😭
장소 조회 기능 구현 과정
저희 팀은 화면에서 장소를 조회하는 기능을 구현하기 위해 MySQL에서 제공하는 공간 데이터와 공간 함수를 활용하기로 하였습니다.
- Point: 좌표 공간의 한 지점
- LineString: 다수의 Point를 연결해주는 선분
- Polygon: 다수의 선분들이 연결되어 닫혀있는 상태
장소 데이터를 Point 타입으로 저장하고, 화면 크기에 해당하는 Polygon을 생성하여 공간 함수를 사용하여 해당 Polygon 내에 있는 장소를 표시하고자 하였습니다.
먼저, 장소의 위도와 경도 데이터를 이용하여 Point 타입의 공간 데이터를 생성하였습니다.
public void makePointData(List<Place> places) {
for (Place place : places) {
Point point = geometryFactory.createPoint(new Coordinate(place.getLongitude(), place.getLatitude()));
point.setSRID(SRID);
PlacePosition placePosition = PlacePosition.builder()
.place(place)
.location(point)
.build();
placePositionRepository.save(placePosition);
}
}
이때 SRID 값은 4326으로 설정하였으며, 이는 GPS의 기준이 되는 WGS84 시스템을 의미합니다.
아래와 같이 공간데이터를 생성하였습니다.
그 다음으로, 프론트엔드 개발자로부터 다음 4가지 값을 받습니다.
- 화면 중앙의 위도와 경도 값
- 화면에서의 최대 위도와 경도 값
이 값을 바탕으로 Polygon을 생성합니다.
private Polygon generatePolygon(double latitude, double longitude, double maxLatitude, double maxLongitude) {
Coordinate[] vertexes = createVertexes(latitude, longitude, maxLatitude, maxLongitude);
Polygon polygon = geometryFactory.createPolygon(vertexes);
polygon.setSRID(SRID);
return polygon;
}
private Coordinate[] createVertexes(double latitude, double longitude, double maxLatitude, double maxLongitude) {
double latitudeDelta = calcLatitudeDelta(maxLatitude, latitude);
double longitudeDelta = calcLongitudeDelta(maxLongitude, longitude);
double minLatitude = latitude - latitudeDelta;
double minLongitude = longitude - longitudeDelta;
return new Coordinate[] {
new Coordinate(maxLongitude, minLatitude),
new Coordinate(maxLongitude, maxLatitude),
new Coordinate(minLongitude, maxLatitude),
new Coordinate(minLongitude, minLatitude),
new Coordinate(maxLongitude, minLatitude)
};
}
private double calcLatitudeDelta(double maxLatitude, double latitude) {
return maxLatitude - latitude;
}
private double calcLongitudeDelta(double maxLongitude, double longitude) {
return maxLongitude - longitude;
}
위 4가지 값을 활용하여 화면에서의 최소 위도와 경도 값, 최대 위도와 경도 값을 기반으로 Polygon을 생성합니다.
결과적으로 아래와 같이 빨간색 사각형의 Polygon이 생성됩니다.
다음으로, MySQL에서 제공하는 공간 함수를 사용하여 빨간색 Polygon 내에 있는 장소 Point 데이터를 조회하는 쿼리를 작성하였습니다. Hibernate 5이후, 공간 데이터를 공식적으로 지원하게 되어 JPQL을 통해 공간 함수를 사용할 수 있습니다!
@Query("SELECT p FROM PlacePosition pp JOIN pp.place p WHERE ST_Contains(:polygon, pp.location)")
List<Place> findPlaceByCoordinate(@Param("polygon") Polygon polygon);
ST_Contains의 대한 설명은 아래와 같습니다.
완성
결과적으로, 현재 화면내에 반려견 동반 가능 시설들이 마커로 표시되는 지도 화면을 완성하였습니다.
참고자료
한국문화정보원_전국 반려동물 동반 가능 문화시설 위치 데이터_20221130
- 문화여가 시설의 반려동물 전용 정보 및 동반 가능 여부 등 상세 정보를 포함하고 있는 데이터입니다.<br/>- 컬럼 "최종작성일" 기준으로 구축되었기 때문에, 시설 별 관리 정책의 변동에 따라
www.data.go.kr
MySQL :: MySQL 8.0 Reference Manual :: 14.16.1 Spatial Function Reference
MySQL 8.0 Reference Manual / ... / Functions and Operators / Spatial Analysis Functions / Spatial Function Reference 14.16.1 Spatial Function Reference The following table lists each spatial function and provides a short description of eac
dev.mysql.com
'Spring' 카테고리의 다른 글
[Spring] 놀멍 서비스 개발 일지 - 로그 시스템 구축하기1 (3) | 2025.01.25 |
---|---|
[Spring] 놀멍 서비스 개발 일지 - 지도 화면 개발하기2(공간 인덱스 적용) (0) | 2025.01.07 |
[Spring] Redis 테스트 환경 구축하기(Embedded Redis) (2) | 2024.12.31 |
[Spring] URL 이미지 리사이징 후, S3에 업로드 (3) | 2024.07.28 |
[Spring] Google STT(Speech-to-Text) 서비스 사용하기 (2) | 2024.06.30 |
느리더라도 단단하게 성장하고자 합니다!
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!