Skip to content
Snippets Groups Projects
Commit b2502937 authored by Steve Agalloco's avatar Steve Agalloco Committed by Alex Reisner
Browse files

added support for mongo_mapper

parent 2707ecae
No related branches found
No related tags found
No related merge requests found
......@@ -4,6 +4,7 @@ require "geocoder/cache"
require "geocoder/request"
require "geocoder/models/active_record"
require "geocoder/models/mongoid"
require "geocoder/models/mongo_mapper"
module Geocoder
extend self
......
require 'geocoder/models/base'
require 'geocoder/models/mongodb_base'
module Geocoder
module Model
module MongoMapper
include Base
include MongoDBBase
def self.included(base); base.extend(self); end
private # --------------------------------------------------------------
def geocoder_file_name; "mongo_mapper"; end
def geocoder_module_name; "MongoMapper"; end
def geocoder_init(options)
super(options)
ensure_index [[ geocoder_options[:coordinates], Mongo::GEO2D ]],
:min => -180, :max => 180 # create 2d index
end
end
end
end
require 'geocoder'
module Geocoder
##
# Methods for invoking Geocoder in a model.
#
module Model
module MongoDBBase
##
# Set attribute names and include the Geocoder module.
#
def geocoded_by(address_attr, options = {}, &block)
geocoder_init(
:geocode => true,
:user_address => address_attr,
:coordinates => options[:coordinates] || :coordinates,
:geocode_block => block
)
end
##
# Set attribute names and include the Geocoder module.
#
def reverse_geocoded_by(coordinates_attr, options = {}, &block)
geocoder_init(
:reverse_geocode => true,
:fetched_address => options[:address] || :address,
:coordinates => coordinates_attr,
:reverse_block => block
)
end
private # ----------------------------------------------------------------
def geocoder_init(options)
unless geocoder_initialized?
@geocoder_options = {}
require "geocoder/stores/#{geocoder_file_name}"
include eval("Geocoder::Store::" + geocoder_module_name)
end
@geocoder_options.merge! options
end
def geocoder_initialized?
begin
included_modules.include? eval("Geocoder::Store::" + geocoder_module_name)
rescue NameError
false
end
end
end
end
end
require 'geocoder/models/base'
require 'geocoder/models/mongodb_base'
module Geocoder
module Model
module Mongoid
include Base
include MongoDBBase
def self.included(base); base.extend(self); end
##
# Set attribute names and include the Geocoder module.
#
def geocoded_by(address_attr, options = {}, &block)
geocoder_init(
:geocode => true,
:user_address => address_attr,
:coordinates => options[:coordinates] || :coordinates,
:geocode_block => block
)
end
##
# Set attribute names and include the Geocoder module.
#
def reverse_geocoded_by(coordinates_attr, options = {}, &block)
geocoder_init(
:reverse_geocode => true,
:fetched_address => options[:address] || :address,
:coordinates => coordinates_attr,
:reverse_block => block
)
end
private # --------------------------------------------------------------
def geocoder_file_name; "mongoid"; end
......
require 'geocoder/stores/base'
module Geocoder::Store
module MongoMapper
include Base
def self.included(base)
base.class_eval do
scope :geocoded, lambda {
where(geocoder_options[:coordinates].ne => nil)
}
scope :not_geocoded, lambda {
where(geocoder_options[:coordinates] => nil)
}
scope :near, lambda{ |location, *args|
coords = Geocoder::Calculations.extract_coordinates(location)
radius = args.size > 0 ? args.shift : 20
options = args.size > 0 ? args.shift : {}
# Use BSON::OrderedHash if Ruby's hashes are unordered.
# Conditions must be in order required by indexes (see mongo gem).
empty = RUBY_VERSION.split('.')[1].to_i < 9 ? BSON::OrderedHash.new : {}
conds = empty.clone
conds[:coordinates] = empty.clone
conds[:coordinates]["$nearSphere"] = coords.reverse
conds[:coordinates]["$maxDistance"] = \
Geocoder::Calculations.distance_to_radians(radius, options[:units] || :mi)
if obj = options[:exclude]
conds[:_id.ne] = obj.id
end
where(conds)
}
end
end
##
# Coordinates [lat,lon] of the object.
# This method always returns coordinates in lat,lon order,
# even though internally they are stored in the opposite order.
#
def to_coordinates
coords = send(self.class.geocoder_options[:coordinates])
coords.is_a?(Array) ? coords.reverse : []
end
##
# Look up coordinates and assign to +latitude+ and +longitude+ attributes
# (or other as specified in +geocoded_by+). Returns coordinates (array).
#
def geocode
do_lookup(false) do |o,rs|
r = rs.first
unless r.coordinates.nil?
o.send :write_attribute, self.class.geocoder_options[:coordinates], r.coordinates.reverse
end
r.coordinates
end
end
##
# Look up address and assign to +address+ attribute (or other as specified
# in +reverse_geocoded_by+). Returns address (string).
#
def reverse_geocode
do_lookup(true) do |o,rs|
r = rs.first
unless r.address.nil?
o.send :write_attribute, self.class.geocoder_options[:fetched_address], r.address
end
r.address
end
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment