PostGIS 덕분에
최근에는 MySQL대신 PostgresQL을 사용하고 있습니다. 테이블에서 필드를 추가/삭제하는 경우에도 table lock이 걸리지 않는다는 점1이 가장 큰 이유였습니다. 손에 익기까지 시간이 좀걸리긴 하지만, 서비스 다운타임을 최소화 시켜줄 수 있지 않을까 생각합니다.
PostGIS는 설치과정이 좀 복잡한데요. gist에서 올바른 설치 법을 발견했습니다. 몇가지 오류를 수정해서 gist에 올렸습니다. (우분투버전도 있습니다.)
레일즈에서 사용하려면, 젬이 필요한데, rgeo + activerecord-postgis-adapter 조합이 제일 편한 듯 합니다.
사실, 예전부터 실무에서 이 조합을 적용해보고 싶었지만 적당한 데이터가 없었습니다. 다행히 이번 과제에서 아주 딱 맞는 상황을 발견해서 적용할 수 있었습니다.
다음은 작업하던 데이터 중 일부인데요. “주소-경도-위도-도시이름” 이 차례로 들어가있습니다.
이를 처리하기 위해서 모델 데이터베이스에 필드를 추가했습니다.
# PostGIS를 도입하면 decimal 대신 point 를 쓸수있다.
#t.decimal :longitude, :precision=>10, :scale=>6
#t.decimal :latitude, :precision=>10, :scale=>6
t.point :gps, :geographic=>true
gps 라는 필드에는 x,y (위도,경도)를 입력할 수 있습니다. 이것만으로는 별로 의미가 없어보입니다. 중요한 것은 아래의 nearby_to 라는 녀석입니다. 모델쪽 클래스에 이렇게 적어두면
scope :nearby_to,
lambda { !hotel, max_distance|
where("ST_DWithin(gps, ?, ?) AND id != ?", hotel.gps, max_distance, hotel.id)
}
뷰에서 이렇게 사용할 수 있습니다.
<h6>근처의 호텔들</h6>
<% nears = Hotel.nearby_to(@hotel, 600).order(:name)
nears.each do |hotel| %>
<%=link_to hotel.name, hotel%>(<%=hotel.longitude%>)
<% end %>
이 녀석과 구글맵 API를 잘 연동하면, 여러가지 조작이 가능하겠구요. 위도/경도 가 포함된 데이터를 처리할 때도 꽤 편하게 응용할 수 있었습니다.
뭔가 그럴싸한 젬이라도 하나 올리면서 포스팅을 하면 좋을텐데 말이죠. 데이터에 NDA라던가 하는 것들이 걸려있어서 오픈할만한 것들이 별로 없네요. 언젠가는 오픈소스 할만한 것이 있겠습니다만…
레일즈와 PostGIS 연동은 link을 참고했습니다.