mongoid_geo 0.4.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.textile +32 -10
- data/lib/mongoid/geo/fields.rb +6 -1
- data/lib/mongoid/geo/geo_near.rb +20 -50
- data/lib/mongoid/geo/unit.rb +83 -0
- data/lib/mongoid/geo.rb +1 -0
- metadata +14 -13
    
        data/README.textile
    CHANGED
    
    | @@ -123,9 +123,9 @@ With the new @:geo@ option supplied by _mongoid-geo_ : | |
| 123 123 | 
             
              Mongoid::Geo.spherical = true
         | 
| 124 124 | 
             
            </pre>
         | 
| 125 125 |  | 
| 126 | 
            -
            h2. News update ( | 
| 126 | 
            +
            h2. News update (May 9, 2011)
         | 
| 127 127 |  | 
| 128 | 
            -
             | 
| 128 | 
            +
            The geoNear queries can now convert the result into a Mongoid::Criteria, where distance from a given location is sorted in either descending or ascending (default) order
         | 
| 129 129 |  | 
| 130 130 | 
             
            <pre>
         | 
| 131 131 | 
             
            class Address
         | 
| @@ -145,18 +145,40 @@ class Position | |
| 145 145 | 
             
              field :pos, :type => Array, :geo => true
         | 
| 146 146 | 
             
              ...
         | 
| 147 147 | 
             
            end
         | 
| 148 | 
            +
            </pre>
         | 
| 149 | 
            +
             | 
| 150 | 
            +
            Find all positions sorted nearest to the address loation
         | 
| 151 | 
            +
            @nearest_positions = Position.geoNear(another_address.location, :pos)@
         | 
| 152 | 
            +
             | 
| 153 | 
            +
            Perform distance locations in Speherical mode inside Mongo DB (default is :plane)
         | 
| 154 | 
            +
            @nearest_positions = Position.geoNear(another_address.location, :pos, :mode => :sphere)@
         | 
| 155 | 
            +
             | 
| 156 | 
            +
            Other options supported are: @:num, :maxDistance, :distanceMultiplier, :query@
         | 
| 157 | 
            +
             | 
| 158 | 
            +
            GeoNear distance returns distance in degrees. Use distanceMultiplier to return in Miles or KM.
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            Set :distanceMultiplier to 6371 to get distance in KM
         | 
| 161 | 
            +
            Set :distanceMultiplier to 3963.19 to get distance in Miles
         | 
| 162 | 
            +
             | 
| 163 | 
            +
            You can also use the :unit option instead like this (supports :feet, :meters, :kms, :miles)
         | 
| 164 | 
            +
             | 
| 165 | 
            +
            results = Address.geoNear @center.location, :location, :unit => :km
         | 
| 166 | 
            +
             | 
| 167 | 
            +
            The query result is returned as an Array of Hashies
         | 
| 168 | 
            +
             | 
| 169 | 
            +
            The result can be then converted to a Mongoid::Criteria if needed
         | 
| 170 | 
            +
             | 
| 171 | 
            +
            pp results.as_criteria.to_a.map(&:distance)
         | 
| 172 | 
            +
            pp results.as_criteria(:desc).to_a.map(&:distance)
         | 
| 173 | 
            +
             | 
| 174 | 
            +
            Or converted to an array of Model instances
         | 
| 148 175 |  | 
| 149 | 
            -
             | 
| 150 | 
            -
            nearest_positions = Position.geoNear(another_address.location, :pos)
         | 
| 176 | 
            +
            pp results.to_models.map(&:distance) 
         | 
| 151 177 |  | 
| 152 | 
            -
             | 
| 153 | 
            -
            nearest_positions = Position.geoNear(another_address.location, :pos, :mode => :sphere)
         | 
| 178 | 
            +
            Note that the :fromLocation field, stores the location the distance was last calculated as a hash of the Point it was calculated from
         | 
| 154 179 |  | 
| 155 | 
            -
             | 
| 180 | 
            +
            @[23.5, -47].hash@ 
         | 
| 156 181 |  | 
| 157 | 
            -
            # GeoNear distance returns distance in degrees. Use distanceMultiplier to return in Miles or KM.
         | 
| 158 | 
            -
            # set distanceMultiplier to 6371 to get distance in KM
         | 
| 159 | 
            -
            # set distanceMultiplier to 3963.19 to get distance in Miles
         | 
| 160 182 | 
             
            </pre>
         | 
| 161 183 |  | 
| 162 184 | 
             
            If you need to operate on the Mongoid models referenced by the query result, simply call #to_models on it
         | 
    
        data/lib/mongoid/geo/fields.rb
    CHANGED
    
    | @@ -26,6 +26,11 @@ module Mongoid #:nodoc | |
| 26 26 | 
             
                      end
         | 
| 27 27 |  | 
| 28 28 | 
             
                      define_method("#{meth}=") do |value|
         | 
| 29 | 
            +
                        if options[:geo]
         | 
| 30 | 
            +
                          self.class.send :field, :distance, :type => Float
         | 
| 31 | 
            +
                          self.class.send :field, :fromLocation, :type => String
         | 
| 32 | 
            +
                        end
         | 
| 33 | 
            +
             | 
| 29 34 | 
             
                        if options[:type] == Array && options[:geo]
         | 
| 30 35 | 
             
                          value = case value
         | 
| 31 36 | 
             
                          when String
         | 
| @@ -37,7 +42,7 @@ module Mongoid #:nodoc | |
| 37 42 | 
             
                          end
         | 
| 38 43 | 
             
                          value = value[0..1] if !value.nil?
         | 
| 39 44 | 
             
                        end
         | 
| 40 | 
            -
                        value.reverse! if Mongoid::Geo.spherical && value
         | 
| 45 | 
            +
                        value.reverse! if Mongoid::Geo.spherical && value && !value.kind_of?(BSON::ObjectId)
         | 
| 41 46 | 
             
                        write_attribute(name, value) 
         | 
| 42 47 | 
             
                      end
         | 
| 43 48 |  | 
    
        data/lib/mongoid/geo/geo_near.rb
    CHANGED
    
    | @@ -25,39 +25,38 @@ module Mongoid | |
| 25 25 | 
             
                  end
         | 
| 26 26 | 
             
                end
         | 
| 27 27 |  | 
| 28 | 
            -
                module Distance
         | 
| 29 | 
            -
                  attr_reader :distance
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                  def set_distance dist
         | 
| 32 | 
            -
                    @distance = dist
         | 
| 33 | 
            -
                  end
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
             | 
| 36 28 | 
             
                module Model
         | 
| 37 29 | 
             
                  def to_model
         | 
| 38 30 | 
             
                    m = klass.where(:_id => _id).first.extend(Mongoid::Geo::Distance)
         | 
| 39 | 
            -
                    m. | 
| 31 | 
            +
                    m.distance = distance
         | 
| 40 32 | 
             
                    m
         | 
| 41 33 | 
             
                  end
         | 
| 42 34 | 
             
                end
         | 
| 43 35 |  | 
| 44 36 | 
             
                module Models
         | 
| 45 | 
            -
                  def to_models
         | 
| 37 | 
            +
                  def to_models mode = nil
         | 
| 46 38 | 
             
                    distance_hash = Hash[ self.map {|item| [item._id, item.distance] } ]
         | 
| 39 | 
            +
                    from_hash = Hash[ self.map { |item| [item._id, item.fromLocation] } ]
         | 
| 47 40 |  | 
| 48 41 | 
             
                    ret = to_criteria.to_a.map do |m|
         | 
| 49 | 
            -
                      m. | 
| 50 | 
            -
                      m. | 
| 42 | 
            +
                      m.distance = distance_hash[m._id.to_s]
         | 
| 43 | 
            +
                      m.fromLocation = from_hash[m._id.to_s]
         | 
| 44 | 
            +
                      m.save if mode == :save
         | 
| 51 45 | 
             
                      m
         | 
| 52 46 | 
             
                    end
         | 
| 53 | 
            -
             | 
| 54 47 | 
             
                    ret.sort {|a,b| a.distance <=> b.distance}
         | 
| 55 48 | 
             
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def as_criteria direction = :asc
         | 
| 51 | 
            +
                    to_models(:save)
         | 
| 52 | 
            +
                    ids = first.klass.where().map(&:_id)
         | 
| 53 | 
            +
                    Mongoid::Criteria.new(first.klass).where(:_id.in => ids, :fromLocation => first.fromLocation).send(direction, :distance)
         | 
| 54 | 
            +
                  end      
         | 
| 56 55 |  | 
| 57 56 | 
             
                  def to_criteria
         | 
| 58 | 
            -
                    ids = map(&:_id)
         | 
| 59 | 
            -
                    first.klass.where(:_id.in => ids)
         | 
| 60 | 
            -
                  end
         | 
| 57 | 
            +
                    ids = map(&:_id)  
         | 
| 58 | 
            +
                    Mongoid::Criteria.new(first.klass).where(:_id.in => ids).desc(:distance)
         | 
| 59 | 
            +
                  end      
         | 
| 61 60 | 
             
                end
         | 
| 62 61 |  | 
| 63 62 | 
             
                module Near
         | 
| @@ -97,6 +96,7 @@ module Mongoid | |
| 97 96 | 
             
                      # Calculate distance in KM or Miles if mongodb < 1.7
         | 
| 98 97 | 
             
                      r[distance_meth] ||= calc_distance(r, center, location_attribute, options) if Mongoid::Geo.mongo_db_version < 1.7
         | 
| 99 98 | 
             
                      r['klass'] = klass
         | 
| 99 | 
            +
                      r['from'] = center.hash
         | 
| 100 100 | 
             
                    end
         | 
| 101 101 | 
             
                    query_result
         | 
| 102 102 | 
             
                  end
         | 
| @@ -105,10 +105,11 @@ module Mongoid | |
| 105 105 | 
             
                    qres.map do |qr|
         | 
| 106 106 | 
             
                      res = Hashie::Mash.new(qr['obj'].to_hash).extend(Mongoid::Geo::Model)
         | 
| 107 107 | 
             
                      res.klass = qr['klass']
         | 
| 108 | 
            +
                      res.fromLocation = qr['from']
         | 
| 108 109 | 
             
                      res.distance = qr[distance_meth]
         | 
| 109 110 | 
             
                      res._id = qr['obj']['_id'].to_s
         | 
| 110 111 | 
             
                      res
         | 
| 111 | 
            -
                    end
         | 
| 112 | 
            +
                    end          
         | 
| 112 113 | 
             
                  end
         | 
| 113 114 |  | 
| 114 115 | 
             
                  private
         | 
| @@ -116,39 +117,8 @@ module Mongoid | |
| 116 117 | 
             
                  def distance_multiplier options
         | 
| 117 118 | 
             
                    distanceMultiplier  = options[:distanceMultiplier]
         | 
| 118 119 | 
             
                    return distanceMultiplier if distanceMultiplier && Mongoid::Geo.mongo_db_version >= 1.7
         | 
| 119 | 
            -
             | 
| 120 | 
            -
                     | 
| 121 | 
            -
                    unit_multiplier[options[:unit]] if options[:unit]
         | 
| 122 | 
            -
                  end
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                  def unit_multiplier
         | 
| 125 | 
            -
                    {
         | 
| 126 | 
            -
                      :feet => 0.305,
         | 
| 127 | 
            -
                      :ft => 0.305,
         | 
| 128 | 
            -
                      :m => 1,
         | 
| 129 | 
            -
                      :meters => 1,
         | 
| 130 | 
            -
                      :meter => 1,
         | 
| 131 | 
            -
                      :km => 6371,
         | 
| 132 | 
            -
                      :kms => 6371,
         | 
| 133 | 
            -
                      :mil => 3959,
         | 
| 134 | 
            -
                      :mile => 3959,
         | 
| 135 | 
            -
                      :miles => 3959
         | 
| 136 | 
            -
                    }
         | 
| 137 | 
            -
                  end
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                  def radian_multiplier
         | 
| 140 | 
            -
                    { 
         | 
| 141 | 
            -
                      :feet => 364491.8,
         | 
| 142 | 
            -
                      :ft => 364491.8,
         | 
| 143 | 
            -
                      :m => 111170,
         | 
| 144 | 
            -
                      :meter => 111170,
         | 
| 145 | 
            -
                      :meters => 111170,
         | 
| 146 | 
            -
                      :km => 111.17,
         | 
| 147 | 
            -
                      :kms => 111.17,
         | 
| 148 | 
            -
                      :mil => 69.407,
         | 
| 149 | 
            -
                      :mile => 69.407,
         | 
| 150 | 
            -
                      :miles => 69.407
         | 
| 151 | 
            -
                    }
         | 
| 120 | 
            +
                    return Mongoid::Geo::Unit.distMultiplier(options[:unit]) if options[:unit]
         | 
| 121 | 
            +
                    1
         | 
| 152 122 | 
             
                  end
         | 
| 153 123 |  | 
| 154 124 | 
             
                  def query_results klass, query 
         | 
| @@ -0,0 +1,83 @@ | |
| 1 | 
            +
            module Mongoid
         | 
| 2 | 
            +
              module Geo
         | 
| 3 | 
            +
                class Unit
         | 
| 4 | 
            +
                  class << self
         | 
| 5 | 
            +
                    def key unit = :km
         | 
| 6 | 
            +
                      unit = unit.to_sym
         | 
| 7 | 
            +
                      methods.grep(/_unit/).each do |meth|
         | 
| 8 | 
            +
                        return meth.to_s.chomp('_unit').to_sym if send(meth).include? unit
         | 
| 9 | 
            +
                      end
         | 
| 10 | 
            +
                      raise ArgumentError, "Unknown unit key: #{unit}"
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    def distMultiplier unit = :km
         | 
| 14 | 
            +
                      unit_key = key(unit)
         | 
| 15 | 
            +
                      return radian_multiplier[unit_key] if unit_key && Mongoid::Geo.mongo_db_version >= 1.7      
         | 
| 16 | 
            +
                      unit_multiplier[unit_key] if unit_key
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    def precision
         | 
| 20 | 
            +
                      {
         | 
| 21 | 
            +
                        :feet => 0,
         | 
| 22 | 
            +
                        :meters => 2,
         | 
| 23 | 
            +
                        :kms => 4,
         | 
| 24 | 
            +
                        :miles => 4,
         | 
| 25 | 
            +
                        :radians => 4
         | 
| 26 | 
            +
                      }
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    # from mongoid-geo, as suggested by niedhui :)
         | 
| 30 | 
            +
                    def radian_multiplier
         | 
| 31 | 
            +
                      { 
         | 
| 32 | 
            +
                        :feet => 364491.8,
         | 
| 33 | 
            +
                        :meters => 111170,
         | 
| 34 | 
            +
                        :kms => 111.17,
         | 
| 35 | 
            +
                        :miles => 69.407,
         | 
| 36 | 
            +
                        :radians => 1
         | 
| 37 | 
            +
                      }
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                    def unit_multiplier
         | 
| 41 | 
            +
                      {
         | 
| 42 | 
            +
                        :feet => 0.305,
         | 
| 43 | 
            +
                        :meters => 1,
         | 
| 44 | 
            +
                        :kms => 6371,
         | 
| 45 | 
            +
                        :miles => 3959
         | 
| 46 | 
            +
                      }
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                    def meters_map
         | 
| 50 | 
            +
                      {
         | 
| 51 | 
            +
                       :feet => 3.2808,
         | 
| 52 | 
            +
                       :meters => 1,
         | 
| 53 | 
            +
                       :kms => 0.001,
         | 
| 54 | 
            +
                       :miles => 0.00062137,
         | 
| 55 | 
            +
                       :radians => 111170
         | 
| 56 | 
            +
                      }
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
                  
         | 
| 59 | 
            +
                    protected
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    def feet_unit 
         | 
| 62 | 
            +
                      [:ft, :feet, :foot]
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
                  
         | 
| 65 | 
            +
                    def meters_unit 
         | 
| 66 | 
            +
                      [:m, :meter, :meters]
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    def kms_unit 
         | 
| 70 | 
            +
                      [:km, :kms, :kilometer, :kilometers]
         | 
| 71 | 
            +
                    end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                    def miles_unit 
         | 
| 74 | 
            +
                      [:mil, :mile, :miles]
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    def radians_unit 
         | 
| 78 | 
            +
                      [:rad, :radians]
         | 
| 79 | 
            +
                    end
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
              end
         | 
| 83 | 
            +
            end
         | 
    
        data/lib/mongoid/geo.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: mongoid_geo
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.5.0
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,11 +9,11 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2011-05- | 
| 12 | 
            +
            date: 2011-05-09 00:00:00.000000000Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: rspec
         | 
| 16 | 
            -
              requirement: & | 
| 16 | 
            +
              requirement: &2152937900 !ruby/object:Gem::Requirement
         | 
| 17 17 | 
             
                none: false
         | 
| 18 18 | 
             
                requirements:
         | 
| 19 19 | 
             
                - - ! '>='
         | 
| @@ -21,10 +21,10 @@ dependencies: | |
| 21 21 | 
             
                    version: '2.4'
         | 
| 22 22 | 
             
              type: :development
         | 
| 23 23 | 
             
              prerelease: false
         | 
| 24 | 
            -
              version_requirements: * | 
| 24 | 
            +
              version_requirements: *2152937900
         | 
| 25 25 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 26 26 | 
             
              name: mongoid
         | 
| 27 | 
            -
              requirement: & | 
| 27 | 
            +
              requirement: &2152965320 !ruby/object:Gem::Requirement
         | 
| 28 28 | 
             
                none: false
         | 
| 29 29 | 
             
                requirements:
         | 
| 30 30 | 
             
                - - ! '>='
         | 
| @@ -32,10 +32,10 @@ dependencies: | |
| 32 32 | 
             
                    version: 2.0.1
         | 
| 33 33 | 
             
              type: :runtime
         | 
| 34 34 | 
             
              prerelease: false
         | 
| 35 | 
            -
              version_requirements: * | 
| 35 | 
            +
              version_requirements: *2152965320
         | 
| 36 36 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 37 37 | 
             
              name: bson
         | 
| 38 | 
            -
              requirement: & | 
| 38 | 
            +
              requirement: &2152964860 !ruby/object:Gem::Requirement
         | 
| 39 39 | 
             
                none: false
         | 
| 40 40 | 
             
                requirements:
         | 
| 41 41 | 
             
                - - ! '>='
         | 
| @@ -43,10 +43,10 @@ dependencies: | |
| 43 43 | 
             
                    version: '1.3'
         | 
| 44 44 | 
             
              type: :runtime
         | 
| 45 45 | 
             
              prerelease: false
         | 
| 46 | 
            -
              version_requirements: * | 
| 46 | 
            +
              version_requirements: *2152964860
         | 
| 47 47 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 48 | 
             
              name: activesupport
         | 
| 49 | 
            -
              requirement: & | 
| 49 | 
            +
              requirement: &2152964400 !ruby/object:Gem::Requirement
         | 
| 50 50 | 
             
                none: false
         | 
| 51 51 | 
             
                requirements:
         | 
| 52 52 | 
             
                - - ! '>='
         | 
| @@ -54,10 +54,10 @@ dependencies: | |
| 54 54 | 
             
                    version: 3.0.4
         | 
| 55 55 | 
             
              type: :runtime
         | 
| 56 56 | 
             
              prerelease: false
         | 
| 57 | 
            -
              version_requirements: * | 
| 57 | 
            +
              version_requirements: *2152964400
         | 
| 58 58 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 59 59 | 
             
              name: hashie
         | 
| 60 | 
            -
              requirement: & | 
| 60 | 
            +
              requirement: &2152963940 !ruby/object:Gem::Requirement
         | 
| 61 61 | 
             
                none: false
         | 
| 62 62 | 
             
                requirements:
         | 
| 63 63 | 
             
                - - ! '>='
         | 
| @@ -65,7 +65,7 @@ dependencies: | |
| 65 65 | 
             
                    version: 0.4.0
         | 
| 66 66 | 
             
              type: :runtime
         | 
| 67 67 | 
             
              prerelease: false
         | 
| 68 | 
            -
              version_requirements: * | 
| 68 | 
            +
              version_requirements: *2152963940
         | 
| 69 69 | 
             
            description: Geo spatial extension on Mongoid 2, to add more geo-spatial capabilities
         | 
| 70 70 | 
             
            email:
         | 
| 71 71 | 
             
            - kmandrup@gmail.com
         | 
| @@ -85,6 +85,7 @@ files: | |
| 85 85 | 
             
            - lib/mongoid/geo/index.rb
         | 
| 86 86 | 
             
            - lib/mongoid/geo/inflections.rb
         | 
| 87 87 | 
             
            - lib/mongoid/geo/point.rb
         | 
| 88 | 
            +
            - lib/mongoid/geo/unit.rb
         | 
| 88 89 | 
             
            - lib/mongoid/geo.rb
         | 
| 89 90 | 
             
            - lib/mongoid_geo.rb
         | 
| 90 91 | 
             
            - MIT-LICENSE
         | 
| @@ -110,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 110 111 | 
             
                  version: 1.3.6
         | 
| 111 112 | 
             
            requirements: []
         | 
| 112 113 | 
             
            rubyforge_project: 
         | 
| 113 | 
            -
            rubygems_version: 1. | 
| 114 | 
            +
            rubygems_version: 1.8.0
         | 
| 114 115 | 
             
            signing_key: 
         | 
| 115 116 | 
             
            specification_version: 3
         | 
| 116 117 | 
             
            summary: Adds extra convenience methods for geo-spatial operations etc.
         |