summaryrefslogtreecommitdiff
path: root/redis
diff options
context:
space:
mode:
authorpfreixes <pfreixes@gmail.com>2016-05-16 17:45:50 +0200
committerpfreixes <pfreixes@gmail.com>2016-05-16 17:49:49 +0200
commit4c331411b6f761226cdefb90250912db325d01e4 (patch)
tree748245ebae95f0b6901ed5942db2ac43a972194b /redis
parent273a47e299a499ed0053b8b90966dc2124504983 (diff)
downloadredis-py-4c331411b6f761226cdefb90250912db325d01e4.tar.gz
Implemented support for the GEO commands for Redis 3.2.0
The following commands have been implemented GEOADD, GEODIST, GEOHASH, GEOPOS, GEORADIUS, GEORADIUSBYMEMBER.
Diffstat (limited to 'redis')
-rwxr-xr-xredis/client.py129
1 files changed, 129 insertions, 0 deletions
diff --git a/redis/client.py b/redis/client.py
index 5f86b1d..d47c4dc 100755
--- a/redis/client.py
+++ b/redis/client.py
@@ -2020,6 +2020,135 @@ class StrictRedis(object):
"""
return Script(self, script)
+ # GEO COMMANDS
+ def geoadd(self, name, *values):
+ """
+ Add the specified geospatial items to the specified key identified
+ by the ``name`` argument. The Geospatial items are given as ordered
+ members of the ``values`` argument, each item or place is formed b
+ the triad latitude, longitude and name.
+ """
+ if len(values) % 3 != 0:
+ raise RedisError("GEOADD requires places with lat, lon and name"
+ " values")
+ return self.execute_command('GEOADD', name, *values)
+
+ def geodist(self, name, place1, place2, unit=None):
+ """
+ Return the distance between ``place1`` and ``place2`` members of the
+ ``name`` key.
+ The units must be one o fthe following : m, km mi, ft. By default
+ meters are used.
+ """
+ pieces = [name, place1, place2]
+ if unit and unit not in ('m', 'km', 'mi', 'ft'):
+ raise RedisError("GEODIST invalid unit")
+ elif unit:
+ pieces.append(unit)
+ return self.execute_command('GEODIST', *pieces)
+
+ def geohash(self, name, *values):
+ """
+ Return the geo hash string for each item of ``values`` members of
+ the specified key identified by the ``name``argument.
+ """
+ return self.execute_command('GEOHASH', name, *values)
+
+ def geopos(self, name, *values):
+ """
+ Return the postitions of each item of ``values`` as members of
+ the specified key identified by the ``name``argument. Each position
+ is represented by the pairs lat and lon.
+ """
+ return self.execute_command('GEOPOS', name, *values)
+
+ def georadius(self, name, latitude, longitude, radius, unit=None,
+ withdist=False, withcoord=False, withhash=False, count=None,
+ sort=None, store=None, store_dist=None):
+ """
+ Return the members of the of the specified key identified by the
+ ``name``argument which are within the borders of the area specified
+ with the ``latitude`` and ``longitude`` location and the maxium
+ distnance from the center specified by the ``radius`` value.
+
+ The units must be one o fthe following : m, km mi, ft. By default
+
+ ``withdist`` indicates to return the distances of each place.
+
+ ``withcoord`` indicates to return the latitude and longitude of
+ each place.
+
+ ``withhash`` indicates to return the geohash string of each place.
+
+ ``count`` indicates to return the number of elements up to N.
+
+ ``sort`` indicates to return the places in a sorted way, ASC for
+ nearest to fairest and DESC for fairest to nearest.
+
+ ``store`` indicates to save the places names in a sorted set named
+ with a specific key, each element of the destination sorted set is
+ populated with the score got from the original geo sorted set.
+
+ ``store_dist`` indicates to save the places names in a sorted set
+ named with a sepcific key, instead of ``store`` the sorted set
+ destination score is set with the distance.
+ """
+ return self._georadiusgeneric('GEORADIUS',
+ name, latitude, longitude, radius,
+ unit=unit, withdist=withdist,
+ withcoord=withcoord, withhash=withhash,
+ count=count, sort=sort, store=store,
+ store_dist=store_dist)
+
+ def georadiusbymember(self, name, member, radius, unit=None,
+ withdist=False, withcoord=False, withhash=False,
+ count=None, sort=None, store=None, store_dist=None):
+ """
+ This command is exactly like ``georadius`` with the sole difference
+ that instead of taking, as the center of the area to query, a longitude
+ and latitude value, it takes the name of a member already existing
+ inside the geospatial index represented by the sorted set.
+ """
+ return self._georadiusgeneric('GEORADIUSBYMEMBER',
+ name, member, radius, unit=unit,
+ withdist=withdist, withcoord=withcoord,
+ withhash=withhash, count=count,
+ sort=sort, store=store,
+ store_dist=store_dist)
+
+ def _georadiusgeneric(self, command, *args, **kwargs):
+ pieces = list(args)
+ if kwargs['unit'] and kwargs['unit'] not in ('m', 'km', 'mi', 'ft'):
+ raise RedisError("GEORADIUS invalid unit")
+ elif kwargs['unit']:
+ pieces.append(kwargs['unit'])
+ else:
+ pieces.append('m',)
+
+ for token in ('withdist', 'withcoord', 'withhash'):
+ if kwargs[token]:
+ pieces.append(Token(token.upper()))
+
+ if kwargs['count']:
+ pieces.extend([Token('COUNT'), kwargs['count']])
+
+ if kwargs['sort'] and kwargs['sort'] not in ('ASC', 'DESC'):
+ raise RedisError("GEORADIUS invalid sort")
+ elif kwargs['sort']:
+ pieces.append(Token(kwargs['sort']))
+
+ if kwargs['store'] and kwargs['store_dist']:
+ raise RedisError("GEORADIUS store and store_dist cant be set"
+ " together")
+
+ if kwargs['store']:
+ pieces.extend([Token('STORE'), kwargs['store']])
+
+ if kwargs['store_dist']:
+ pieces.extend([Token('STOREDIST'), kwargs['store_dist']])
+
+ return self.execute_command(command, *pieces)
+
class Redis(StrictRedis):
"""