GeoJSON 객체
- 공간 정보 쿼리의 유형: 교차(intersect), 포함(within), 근접(nearness)
- GeoJSON: JSON 형태로 지형 데이터를 정의하는 포맷
- <field>: { type: <GeoJSON type>, coordinates: <coordinates> }
- type: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection이 있음
- coordinates: 좌표
- 공간 정보 쿼리
- 공간정보 쿼리를 효율적으로 실행
- 공간정보 쿼리의 유형
- $geoIntersects: 주어진 영역과 문서들의 영역에 교집합을 찾아서 반환
- $geoWithin: 영역 안에 포함된 document들 반환
- 입력값으로 폴리곤 계열의 GeoJSON객체, 레거시 좌표로 정의된 Shape도 허용
- $nearSphere: 영역 안에 포함된 문서들을 가까운 순서대로 정렬해서 반환
- GeoJSON을 이용할 때는 2dsphere 인덱스를, 레거시 좌표점을 이용할 때는 2d 인덱스를 사용
공간정보 쿼리 예제
- 샘플 데이터 준비
- places 컬렉션: GeoJSON 형태로 입력, legacyplaces 커렉션: 좌표계로 입력
db.places.insertOne({ name: "제주커피박물관 Baum", location:{ type:"Point",
coordinates: [126.8990639, 33.4397954 ] } })
db.places.insertOne({ name: '신산리 마을카페', location: { type: 'Point',
coordinates: [126.8759347, 33.3765812 ] } })
db.legacyplaces.insertOne({ name: '제주커피박물관 Baum', location:
[126.8990639, 33.4397954 ] })
db.legacyplaces.insertOne({ name: '신산리 마을카페', location:
[126.8759347, 33.3765812 ] })
- $geoIntersects: 특정 위치가 특정 영역에 포함되는 경우의 도큐먼트를 결과로 출력
- 구형 기하학(spherical geometry)을 이용 → 공간정보 인덱스를 사용할거라면 2dsphere를 선택
// ex) 신산리 안에있는 장소 찾기
db.places.find({
location:{
$geoIntersects: {
$geometry: {
type: 'Polygon',
coordinates: [
[[126.86, 33.39], [126.88, 33.39], [126.88, 33.37], [126.86, 33.37], [126.86, 33.39]]
]
}
}
}
})
- $geoWithin: 요청하는 영역안에 포함된 문서들을 반환
// 기본문법 1
{ <location field>: {
$geoWithin: {
$geometry: {
type: "<GeoJSON 오브젝트 타입>",
coordinates: [<coordinates>]
}
}
} }
// 기본문법 2
{ <location field>: {
$geoWithin: {<shape operator>: <coordinates> }
} }
// ex) 신산리 마을회관 5km 내에 있는 장소 찾기
db.legacyplaces.find({
location: {
$geoWithin: {
$centerSphere: [[126.876933, 33.381018], 5/6378.1]
}
}
})
- $near와 $nearSphere
- 영역 안에 포함된 document들을 반환 (거리순으로 정렬 가능)
- 특정 위치에서 가까운 곳을 검색할 수 있음
// 기본 문법 1
{
<location field>: {
$nearSphere: {
$geometry: {
type: "Point",
coordinates: [<longitude>, <latitude>]
},
$minDistance: <distance in meters>,
$maxDistance: <distance in meters>
}
}
}
// 기본 문법 2
{
<location field>: {
$nearSphere: [<x>, <y>],
$minDistance: <distance in meters>,
$maxDistance: <distance in meters>
}
}
// ex) 성산일출봉에서 12km이내의 카페들을 가까운 순서대로 찾기
db.places.createIndex({"location": "2dsphere"}) // $nearSphere를 사용하기위해선 인덱스가 필요함
db.places.find({
location: {
$nearSphere: { // 인덱스필요
$geometry: {
type: "Point",
coordinates: [126.941131, 33.459216]
},
$minDistance: 1000,
$maxDistance: 12000
}
}
})