Browse Source

Added geo location support.

Martin Edenhofer 13 years ago
parent
commit
6e08d1f3d9
3 changed files with 91 additions and 6 deletions
  1. 64 6
      app/models/user.rb
  2. 3 0
      config/environment.rb
  3. 24 0
      lib/gmaps.rb

+ 64 - 6
app/models/user.rb

@@ -1,6 +1,8 @@
 class User < ApplicationModel
-  before_create           :check_name, :check_email, :check_image
-  before_update           :check_password
+  include Gmaps
+
+  before_create           :check_name, :check_email, :check_image, :check_geo
+  before_update           :check_password, :check_geo
   after_create            :cache_delete
   after_update            :cache_delete
   after_destroy           :cache_delete
@@ -191,28 +193,84 @@ Your #{config.product_name} Team
     return data
   end
 
+  # update all users geo data
+  def self.geo_update_all
+    User.all.each { |user|
+      user.geo_update
+      user.save
+    }
+  end
+
+  # update geo data of one user
+  def geo_update
+    address = ''
+    location = ['street', 'zip', 'city', 'country']
+    location.each { |item|
+      if self[item] && self[item] != ''
+        address = address + ',' + self[item]
+      end
+    }
+
+    # return if no address is given
+    return if address == ''
+
+    # dp lookup
+    latlng = Gmaps.geocode(address)
+    if latlng
+      self.preferences['lat'] = latlng[0]
+      self.preferences['lng'] = latlng[1]
+    end
+  end
+
   private
+    def check_geo
+
+      location = ['street', 'zip', 'city', 'country']
+      
+      # check if geo update is needed
+      current = User.find( self.id )
+      current_location = {}
+      location.each { |item|
+        current_location[item] = current[item]
+      }
+      
+      # get full address
+      next_location = {}
+      location.each { |item|
+        next_location[item] = self[item]
+      }
+
+      # return if address hasn't changed and geo data is already available
+      return if ( current_location == next_location ) && ( self.preferences['lat'] && self.preferences['lng'] )
+
+      # geo update
+      self.geo_update
+    end
+
     def check_name
-      if self.firstname && (!self.lastname || self.lastname == '') then
+      if self.firstname && (!self.lastname || self.lastname == '')
         name = self.firstname.split(' ', 2)
         self.firstname = name[0]
         self.lastname  = name[1]
       end
     end
+
     def check_email
-      if self.email then
+      if self.email
         self.email = self.email.downcase
       end
     end
+
     def check_image
       require 'digest/md5'
-      if !self.image || self.image == '' then
-        if self.email then
+      if !self.image || self.image == ''
+        if self.email
           hash = Digest::MD5.hexdigest(self.email)
           self.image = "http://www.gravatar.com/avatar/#{hash}?s=48"
         end
       end
     end
+
     def check_password
       
       # set old password again

+ 3 - 0
config/environment.rb

@@ -13,5 +13,8 @@ require 'google_oauth2_database'
 # load notification factory (replace all tags)
 require 'notification_factory'
 
+# load gmaps lookup
+require 'gmaps'
+
 # Initialize the rails application
 Zammad::Application.initialize!

+ 24 - 0
lib/gmaps.rb

@@ -0,0 +1,24 @@
+module Gmaps
+  def self.geocode(address)
+    url = "http://maps.googleapis.com/maps/api/geocode/json?address=#{CGI::escape address}&sensor=true"
+    response = Net::HTTP.get_response( URI.parse(url) )
+    return if response.code.to_s != '200'
+
+    result = JSON.parse( response.body )
+
+    lat = result['results'].first['geometry']['location']['lat']
+    lng = result['results'].first['geometry']['location']['lng']
+    latlng = [lat,lng]
+  end
+ 
+  def self.reverse_geocode(lat,lng)
+    url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=#{lat},#{lng}&sensor=true"
+    response = Net::HTTP.get_response( URI.parse(url) )
+    return if response.code.to_s != '200'
+
+    result = JSON.parse( response.body )
+ 
+    address = result['results'].first['address_components'].first['long_name']
+    return address
+  end
+end