MongoDB와 GeoJSON을 이용하여 근접 위치 확인하기

2018/09/17

MongoDB와 GeoJSON을 이용하여 근접 위치 확인하기

MongoDB는 NoSQL로 key-value 형태의 BSON(Binary JSON)으로 되어있습니다. ( 스키마가 없어요! )
데이터 저장 형식이 자유로워 MongoDB와 GeoJSON을 이용하면 두 지점간의 거리를 구하거나,
한 지점에서 부터의 일정 반경까지의 거리 계산을 쉽게 할 수 있습니다.

geoJSON이란 위치 정보를 JSON형태로 만든 정보 입니다.
참고 : http://geojson.org/

GeoJSON 객체는 { type: 타입, coordinates: [ 경도, 위도 ] } 형식으로 표현됩니다.
타입에는 Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection 등이 있습니다.
Point를 제외하고는 coordinates: [[경도1, 위도1], [경도2, 위도2], …] 이렇게 여러 점을 한 번에 표현할 수 있습니다.
여러 도형을 표현할 수 있는 게 장점입니다.

아래 몽고 쿼리는 -74, 40.74 를 중심으로 반지름이 10인 원 안에 존재하는 위치정보들을 반환합니다.

db.places.find(
   { loc: { $geoWithin: { $center: [ [-74, 40.74], 10 ] } } }
)

그럼 가장 익숙한 Java/Spring Boot를 이용하여 간단한 위치 기반 API를 만들어 보겠습니다.

Spring Data는 MongoDB- Geospatial를 제공하여 MongoRepository를 상속받아 사용할 수 있습니다.

먼저 MongoDb에 저장할 간단한 LocationEntity를 생성합니다.

@Document(collection = "locations")  
public class LocationEntity {  
    private String id;  
 private String subject;  
 private GeoJsonPoint location;  
  
 public LocationEntity(final String subject, final GeoJsonPoint location) {  
        this.subject = subject;  
 this.location = location;  
  } 
}

다음으로 LocationEntity에 대한 Repository를 생성합니다.

public interface LocationRepository  extends MongoRepository<LocationEntity, String> {  

    List<LocationEntity> findBySubjectAndLocationNear(String sid, Point p, Distance d);  
}

마지막으로 RestController를 이용하여 위도, 경도, 거리를 입력받고
입력된 위도, 경도를 중심으로 키로수 반경에 존재하는 위치 정보들을 리턴합니다.

@RestController
public class LocationResource {
 @Autowired
 private LocationRepository repository;

 @RequestMapping(method = RequestMethod.GET)
 public final List<LocationEntity> getLocations(
   @RequestParam("lat") String latitude,
   @RequestParam("long") String longitude,
   @RequestParam("d") double distance,
   @RequestParam(value = "s", required = false) String subjects) {

   return this.repository.findBySubjectAndLocationNear(subjects,
     new Point(Double.valueOf(longitude), Double.valueOf(latitude)),
     new Distance(distance, Metrics.KILOMETERS));
 }
}

이것 만으로도 넘어 오는 GPS정보를 이용하여 근접 지점들을 확인 할 수 있습니다.
엄청 간단하죠!

뭔가 두서없이 썼네요,
잘못된 정보가 있다면 댓글로 알려주세요!

감사합니다.

Reference


Posted by AN

Post Directory