메뉴

문서정보

목차

Geo-fence

지오펜스(Geo-fence)는 실제 지리적영역에 가상으로 경계를 만드는 것이다. 점 위치 주변을 기준으로 일정반경으로 하는 등 동적으로 만들수 있다. 혹은 학교, 인접 지역 경계등을 미리 정의해서 사용 할 수도 있다.

지오펜스를 사용하는 것을 지오펜싱(geo-fencing)이라고 한다. 위치기반서비스(Location-Based Service 줄여서 LBS)는 geo-fence 영역에 들어가거나 나가는 것을 모니터링 하고 알람을 주는 방식으로 지오펜싱 서비스를 제공한다.

인터넷 서비스에서의 Geofencing

때때로 유저는 공항이나 대형마켓 등에서 위치기반 애플리케이션을 사용하려고 한다. 이 앱이 제대로 작동하려면, 유저가 관심있는 지역 근처에 이동 하거나 관심지역을 빠져나왔을 때를 알아내서 어떤 작업을 수행해야 한다. 이러한 서비스를 위해서 필요한 작업은 아래와 같을 것이다.
  1. 관심지역에 포인트(위도&경도)를 찍고, 일정한 반경으로 지오펜싱 한다.
  2. GPS 등으로 위치 확인이 가능한 모바일 애플리케이션을 이용해서 적당한 주기로 현재의 위치정보를 가져온다.
  3. 현재 위치가 특정 지오펜싱영역에 포함돼 있다면, 여기에 맞는 작업을 수행한다.
지오펜싱서비스의 기반 기술은 정확한 측위로, 정확한 측위가 이루어지지 않는 상태에서는 제대로된 지오펜싱 서비스를 개발 할 수 없다. GPS나 Wifi를 이용한 측위는 내 전공이 아니니(별로 관심도 없고) 측위가 이루어진 상태라고 가정하고 테스트를 진행하려 한다.

엄격한 지오펜싱 서비스를 하려면 지도상에 폴리곤을 그릴 수 있어야 하겠지만 측위 기술의 한계와 사용성 문제로 대부분 포인트 & 반경 위주로 지오펜스를 설정한다. 어차피 측위 기술이 불완전하기 때문에 폴리곤을 그려봤자 별 쓸모가 없다.

 Google Geofencing API

 Google Geofencing API

지오펜싱 서비스를 제공하는 대표적인 회사로 구글이 있다. 구글은 Geofencing API를 제공하는데, 특정 지역에 대한 입/출입을 확인 할 수 있고 이를 이용한 위치기반 애플리케이션의 개발이 가능하다. API 개발자는 지오펜스의 위도,경도,반경,지속시간 과 전환 유형등이 설정된 지오펜스 객체를 만들 수 있다. 이 지오펜스 객체는 지오펜스 영역에서 발생하는 전환유형을 만족하는 경우 이벤트를 발생시켜서 특별한 펑션을 실행 할 수 있다.

예를들어 유저가 쇼핑몰 센터에 진입했다면, 유저의 취향에 맞춰서 적당한 상품 혹은 이벤트 등을 추천할 수 있을 것이다.

geofence 안에 있는지 확인

거리연산 기반

geo-fence를 원으로만 설정 할 경우 아래와 같은 느낌으로 표현될 것이다.

 geofence

마커(marker)가 디바이스의 위치라고 가정해보자. 디바이스는 자신의 위치를 기준으로 어떤 geofence 객체에 포함돼 있는지 근처에 어떤 geofence 객체가 있는지를 확인 할 수 있어야 한다. 그 다음 포인트와의 거리와 반경을 비교하는 것으로 내가 어떤 오브젝트에 포함되는지를 알아낼 수 있다.

연산만으로 어떤 geofence객체에 포함돼 있는지 알 수 있는 방법이 있다. 디바이스를 근처로 꽤 큰 geofence를 설정하고, 이 안에 있는 point를 찾은 다음 point를 가지고 있는 geofence 객체의 반경을 연산하는 것이다. 아래 그림을 보자.

 반경 연산만으로 geofence 확인

마커는 디바이스의 위치다. 디바이스를 중심으로 특정 반경내의 genfence 객체를 select 한 결과 4개의 객체가 발견됐다. 이제 각 객체의 반경을 알아내면, 어떤 genfence 객체에 포함되는지 알 수 있다.

간단하긴 하지만, 제대로된 연산결과를 위해서는 geofence 반경보다 충분히 더 큰 반경으로 계산을 해야 한다는 문제가 있다. 예를 들어 100km짜리 geofence가 있다면, 100km 반경 이내의 모든 object를 검사해야 한다. 연산량이 크게 늘어날 수 있다.

축적별로 geofence 객체를 만들어서 연산을 줄이는 방법을 쓸 수 있을 것이다. 애초에 Circle로 geofence 객체를 만드는데 수십 km가 넘을리는 없을테고, 수십 km를 넘어가는 수준이라면 GIS에서 사용하는 (폴리곤)geofence를 사용하는게 맞을 것이다. 이런 점에서 본다면 거리연산만으로 genfence를 검사하는 것도 유연성이 떨어질 뿐 나쁘지 않은 방법일 수 있다.

GeoHash를 이용한 Geofencing

GeoHash를 이용한 geofence 설정에 대해서 살펴보자. Geohash를 이용하면 특정영역을 문자열해시값으로 만들수 있다. 이 문자열은 B-tree 색인을 할 수 있기 때문에, 디바이스의 위치가 어떤 geofence 영역에 포함됐는지는 Select 만으로 검사 할 수 있다. 아래 그림을 보자.

 geohash를 이용한 geofencing

구글 마커가 있는 영역으로 부터 반경 300m 정도의 geofence 객체를 만들려고 한다. 간단한 계산을 이용해서 300m 반경을 담기 위해서는 6 Length 의 Geohash를 이용하면 된다는 것을 알 수 있다. 이제 geofence 객체를 완전히 포함하는 9개의 geohash 사각형을 얻을 수 있다. geofence 객체의 이름이 "myPlace"라고 하면 아래와 같은 색인테이블을 만들 수 있다.
Index Object
wydq50 myPlace
wydq52 myPlace
wydq4b myPlace
wydmgr myPlace
wydmgp myPlace
wydmgn myPlace
wydmgq myPlace
wydmfy myPlace
wydmfz myPlace
myPlace 객체는 아래와 같이 정의 할 수 있을 것이다.
type geoFence struct {
    name   string   // geofence 이름
    lat    float64  // 위도
    lon    float64  // 경도
    rad    int      // 반경
}

// geoFence 내부에 있는지 확인한다. 
// geoFence 경계와 중심에서의 거리도 반환한다.
func (g *geoFence) isInner(lat, lng float64) (int,int,bool) {
    // 위도&경도로 부터 거리를 계산하고 g.rad와 비교한다.
}
실제로 구현할 때는, geofence의 반경에 따라서 geohash의 해상도(길이)가 달라지기 때문에 즉, 여러 개의 차원이 있을 수 있어야 머리를 좀 굴려야 한다.

테스트를 위해서 두 개의 geofence를 만들었다. 첫번째 geofence는 7 Length 짜리다. 아래의 해시값을 가지고 있다.
37.3767785472602,127.11788707087726
GeoHash : wydksshrt2w8
wydkss7 wydkssk wydkssm
wydkss5 wydkssh wydkssj
wydkseg wydkseu wydksev 

두번째 geofence는 6 Length 짜리다.
37.376433479773276,127.12425028433859
GeoHash : wydksu1j98pq
wydkst wydksv wydktj
wydkss wydksu wydkth
wydkse wydksg wydkt5

 2개 이상의 geofence 객체 검색

이미지의 "2개 geofence 영역에 포함되는"위치에 디바이스가 있을 경우, 2개 geofence를 모두 검색할 수 있어야 한다. 각 축적에 맞는 geohash length로 색인을 하면, 2번의 Select 연산으로 디바이스가 포함된 geofence를 구할 수 있다.
  1. SELECT geoObject FROM geofence WHERE geohash = wydkssj
  2. SELECT geoObject from geofence WHERE geohash = wydkss
이 방식대로라면 디바스가 포함된 geofence 객체를 찾기 위해서 2번 이상의 질의가 필요할 수 있다. Geohash는 11 length까지의 해상도를 가지고 있다. 최대 11번의 질의가 필요 할 수 있겠으나 9 length가 4.8m x 4.8m 이므로 현실적으로는 8 length(38.2m x 19m) 부터 사용한다고 봐야 한다. 그리고 4 length 가 39.1km x 19.5 km 인데, 이 범위도 사용 하지는 않을 거다. 그렇다면 8 ~ 5 length, 최대 4번의 쿼리로 봐야 할 것이다. 여기에 6 length 이상의 geofence 객체라면 Redis(Redis는 GeoHash 연산을 지원한다.)에 색인 할 수 있을 거다.

ElasticSearch와 Geohash