module Oxblood module Commands module Geo # Add one or more geospatial items in the geospatial index represented # using a sorted set. # @see https://redis.io/commands/geoadd # # @param [String] key # @param [Array<[String, String, String]>] items # Geospatial items (longitude, latitude, member) # # @return [Integer] The number of elements added to the sorted set, # not including elements already existing for which the score was updated. def geoadd(key, *items) run(*items.unshift(:GEOADD, key)) end # Returns members of a geospatial index as standard geohash strings. # @see https://redis.io/commands/geohash # # @param [String] key # @param [String, Array] members # # @return [Array] The command returns an array where each element is # the Geohash corresponding to each member name passed as argument to the command. def geohash(key, *members) run(*members.unshift(:GEOHASH, key)) end # Returns longitude and latitude of members of a geospatial index. # @see https://redis.io/commands/geopos # # @param [String] key # @param [String, Array] members # # @return [Array] an array where each element is a two elements array # representing longitude and latitude (x,y) of each member name passed # as argument to the command. # Non existing elements are reported as `nil` elements of the array. def geopos(key, *members) run(*members.unshift(:GEOPOS, key)) end # Returns the distance between two members of a geospatial index. # @see https://redis.io/commands/geodist # # @param [String] key # @param [String] member1 name of geospatial index member # @param [String] member2 name of geospatial index member # @param [nil, String] unit that could be one of the following and # defaults to meters: m (meters), km (kilometers), mi (miles), ft (feet). # # @return [nil, String] The command returns the distance as a double # (represented as a string) in the specified unit, or nil if one or # both elements are missing. def geodist(key, member1, member2, unit = nil) if unit run(:GEODIST, key, member1, member2, unit) else run(:GEODIST, key, member1, member2) end end # Query a sorted set representing a geospatial index to fetch members # matching a given maximum distance from a point. # @see https://redis.io/commands/georadius # # @param [String] key # @param [String] longitude # @param [String] latitude # @param [Integer] radius # @param [Symbol] unit that could be one of the following and defaults to # meters: m (meters), km (kilometers), mi (miles), ft (feet). # @param [Hash] opts # # @option opts [Boolean] :withcoord Also return the longitude, latitude # coordinates of the matching items. # @option opts [Boolean] :withdist Also return the distance of # the returned items from the specified center. The distance is returned # in the same unit as the unit specified as the radius argument of # the command. # @option opts [Boolean] :withhash Also return the raw geohash-encoded # sorted set score of the item, in the form of a 52 bit unsigned integer. # This is only useful for low level hacks or debugging and is otherwise # of little interest for the general user. # @option opts [Symbol] :order The command default is to return unsorted # items. Two different sorting methods can be invoked using the following # two options: # - ASC: from the nearest to the farthest, relative to the center. # - DESC: from the farthest to the nearest, relative to the center. # @option opts [Integer] :count limit the results to the first N matching items. # @option opts [String] :store generates a valid geo index and stores # result to key # @option opts [String] :storedist stores calculated distances to key. # # @return [Array] See https://redis.io/commands/georadius#return-value # @return [Integer] if STORE or STOREDIST option was used def georadius(key, longitude, latitude, radius, unit, opts = {}) args = [:GEORADIUS, key, longitude, latitude, radius, unit] add_georadius_opts!(args, opts) run(*args) end # Query a sorted set representing a geospatial index to fetch members # matching a given maximum distance from a member. # @see https://redis.io/commands/georadiusbymember # # @param [String] key # @param [String] member # @param [Integer] radius # @param [Symbol] unit that could be one of the following and defaults to # meters: m (meters), km (kilometers), mi (miles), ft (feet). # @param [Hash] opts # # @option opts [Boolean] :withcoord Also return the longitude, latitude # coordinates of the matching items. # @option opts [Boolean] :withdist Also return the distance of # the returned items from the specified center. The distance is returned # in the same unit as the unit specified as the radius argument of # the command. # @option opts [Boolean] :withhash Also return the raw geohash-encoded # sorted set score of the item, in the form of a 52 bit unsigned integer. # This is only useful for low level hacks or debugging and is otherwise # of little interest for the general user. # @option opts [Symbol] :order The command default is to return unsorted # items. Two different sorting methods can be invoked using the following # two options: # - ASC: from the nearest to the farthest, relative to the center. # - DESC: from the farthest to the nearest, relative to the center. # @option opts [Integer] :count limit the results to the first N matching items. # @option opts [String] :store generates a valid geo index and stores # result to key # @option opts [String] :storedist stores calculated distances to key. # # @return [Array] See https://redis.io/commands/georadius#return-value # @return [Integer] if STORE or STOREDIST option was used def georadiusbymember(key, member, radius, unit, opts = {}) args = [:GEORADIUSBYMEMBER, key, member, radius, unit] add_georadius_opts!(args, opts) run(*args) end private # @note Mutates args argument! def add_georadius_opts!(args, opts) args << :WITHCOORD if opts[:withcoord] args << :WITHDIST if opts[:withdist] args << :WITHHASH if opts[:withhash] if order = opts[:order] args << order end if count = opts[:count] args.push(:COUNT, count) end if store_key = opts[:store] args.push(:STORE, store_key) end if storedist_key = opts[:storedist] args.push(:STOREDIST, storedist_key) end end end end end