<commit_before>require 'geocoder/stores/base'

##
# Add geocoding functionality to any ActiveRecord object.
#
module Geocoder::Store
  module ActiveRecord
    include Base

    ##
    # Implementation of 'included' hook method.
    #
    def self.included(base)
      base.extend ClassMethods
      base.class_eval do

        # scope: geocoded objects
        scope :geocoded, lambda {
          {:conditions => "#{geocoder_options[:latitude]} IS NOT NULL " +
            "AND #{geocoder_options[:longitude]} IS NOT NULL"}}

        # scope: not-geocoded objects
        scope :not_geocoded, lambda {
          {:conditions => "#{geocoder_options[:latitude]} IS NULL " +
            "OR #{geocoder_options[:longitude]} IS NULL"}}

        ##
        # Find all objects within a radius of the given location.
        # Location may be either a string to geocode or an array of
        # coordinates (<tt>[lat,lon]</tt>). Also takes an options hash
        # (see Geocoder::Orm::ActiveRecord::ClassMethods.near_scope_options
        # for details).
        #
        scope :near, lambda{ |location, *args|
          latitude, longitude = Geocoder::Calculations.extract_coordinates(location)
          if latitude and longitude
            near_scope_options(latitude, longitude, *args)
          else
            where(:id => false) # no results if no lat/lon given
          end
        }


        ##
        # Find all objects within the area of a given bounding box.
        # Bounds must be an array of locations specifying the southwest
        # corner followed by the northeast corner of the box
        # (<tt>[[sw_lat, sw_lon], [ne_lat, ne_lon]]</tt>).
        #
        scope :within_bounding_box, lambda{ |bounds|
          return where(:id => false) unless bounds.flatten!.length == 4

          sw_lat, sw_lng, ne_lat, ne_lng = bounds
          spans = "latitude BETWEEN #{sw_lat} AND #{ne_lat} AND "
          spans << if sw_lng > ne_lng   # Handle a box that spans 180
            "longitude BETWEEN #{sw_lng} AND 180 OR longitude BETWEEN #{ne_lng} and -180"
          else
            "longitude BETWEEN #{sw_lng} AND #{ne_lng}"
          end
          { :conditions => spans }
        }
      end
    end

    ##
    # Methods which will be class methods of the including class.
    #
    module ClassMethods

      private # ----------------------------------------------------------------

      ##
      # Get options hash suitable for passing to ActiveRecord.find to get
      # records within a radius (in miles) of the given point.
      # Options hash may include:
      #
      # * +:units+   - <tt>:mi</tt> (default) or <tt>:km</tt>; to be used
      #   for interpreting radius as well as the +distance+ attribute which
      #   is added to each found nearby object
      # * +:bearing+ - <tt>:linear</tt> (default) or <tt>:spherical</tt>;
      #   the method to be used for calculating the bearing (direction)
      #   between the given point and each found nearby point;<commit_msg>Fix: handle nil values in :within_bounding_box<commit_after>require 'geocoder/stores/base'

##
# Add geocoding functionality to any ActiveRecord object.
#
module Geocoder::Store
  module ActiveRecord
    include Base

    ##
    # Implementation of 'included' hook method.
    #
    def self.included(base)
      base.extend ClassMethods
      base.class_eval do

        # scope: geocoded objects
        scope :geocoded, lambda {
          {:conditions => "#{geocoder_options[:latitude]} IS NOT NULL " +
            "AND #{geocoder_options[:longitude]} IS NOT NULL"}}

        # scope: not-geocoded objects
        scope :not_geocoded, lambda {
          {:conditions => "#{geocoder_options[:latitude]} IS NULL " +
            "OR #{geocoder_options[:longitude]} IS NULL"}}

        ##
        # Find all objects within a radius of the given location.
        # Location may be either a string to geocode or an array of
        # coordinates (<tt>[lat,lon]</tt>). Also takes an options hash
        # (see Geocoder::Orm::ActiveRecord::ClassMethods.near_scope_options
        # for details).
        #
        scope :near, lambda{ |location, *args|
          latitude, longitude = Geocoder::Calculations.extract_coordinates(location)
          if latitude and longitude
            near_scope_options(latitude, longitude, *args)
          else
            where(:id => false) # no results if no lat/lon given
          end
        }


        ##
        # Find all objects within the area of a given bounding box.
        # Bounds must be an array of locations specifying the southwest
        # corner followed by the northeast corner of the box
        # (<tt>[[sw_lat, sw_lon], [ne_lat, ne_lon]]</tt>).
        #
        scope :within_bounding_box, lambda{ |bounds|
          sw_lat, sw_lng, ne_lat, ne_lng = bounds.flatten!
          return where(:id => false) unless sw_lat && sw_lng && ne_lat && ne_lng

          spans = "latitude BETWEEN #{sw_lat} AND #{ne_lat} AND "
          spans << if sw_lng > ne_lng   # Handle a box that spans 180
            "longitude BETWEEN #{sw_lng} AND 180 OR longitude BETWEEN #{ne_lng} and -180"
          else
            "longitude BETWEEN #{sw_lng} AND #{ne_lng}"
          end
          { :conditions => spans }
        }
      end
    end

    ##
    # Methods which will be class methods of the including class.
    #
    module ClassMethods

      private # ----------------------------------------------------------------

      ##
      # Get options hash suitable for passing to ActiveRecord.find to get
      # records within a radius (in miles) of the given point.
      # Options hash may include:
      #
      # * +:units+   - <tt>:mi</tt> (default) or <tt>:km</tt>; to be used
      #   for interpreting radius as well as the +distance+ attribute which
      #   is added to each found nearby object
      # * +:bearing+ - <tt>:linear</tt> (default) or <tt>:spherical</tt>;
      #   the method to be used for calculating the bearing (direction)
      #   between the given point and each found nearby point;
{'fraction_non_alphanumeric': 0.11663102483961178, 'fraction_numerical': 0.0031255140648132917, 'mean_word_length': 2.116350589441312, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7374148', 'n_tokens_mistral': 1785, 'n_tokens_neox': 1680, 'n_words': 582}